Browse Source

Updates

Updated /spawn details to include a radius option if no target is selected, eg. /spawn details 5 - for a radius of 5.  Gets some general spawn information (location id, spawn id, widget id, etc.)

Character Save / WritePlayerStatistic updated to check if characterid is set (in case client disconnects before character loads)

Default char_id of 0 set for Player class

Added a sql_updates.sql file for WORLD with _DEBUG define so we can more easily push updates made in game to each other
Image 4 years ago
parent
commit
45d58b4766

+ 9 - 3
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -3126,9 +3126,15 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					safe_delete(packet);
 				}
 			}
-			else{
-				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Syntax: /spawn details ");
-				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "This will display information about the currently selected spawn");
+			else if (sep && sep->arg[0][0] && sep->IsNumber(0))
+			{
+				float radius = atof(sep->arg[0]);
+				if ( !client->GetCurrentZone()->SendRadiusSpawnInfo(client, radius) )
+					client->SimpleMessage(CHANNEL_COLOR_YELLOW, "No results in the radius were found.");
+			}
+			else {
+				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Syntax: /spawn details (radius)");
+				client->SimpleMessage(CHANNEL_COLOR_YELLOW, "This will display information about the currently selected spawn, or in the case of specifying a numerical radius will show minor details about spawns in the players radius.");
 			}
 			break;
 								   }

+ 1 - 0
EQ2/source/WorldServer/Player.cpp

@@ -47,6 +47,7 @@ extern MasterTitlesList master_titles_list;
 extern MasterLanguagesList master_languages_list;
 
 Player::Player(){
+	char_id = 0;
 	group = 0;
 	appearance.pos.grid_id = 0;
 	spawn_index = 0;

+ 1 - 1
EQ2/source/WorldServer/Spawn.cpp

@@ -41,7 +41,7 @@ Spawn::Spawn(){
 	group_id = 0;
 	size_offset = 0;
 	merchant_id = 0;
-	memset(&appearance, 0, sizeof(appearance)); 
+	memset(&appearance, 0, sizeof(AppearanceData)); 
 	memset(&basic_info, 0, sizeof(BasicInfoStruct)); 
 	appearance.encounter_level =6;
 	size = 32;

+ 7 - 2
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -1118,7 +1118,12 @@ void WorldDatabase::LoadWidgets(ZoneServer* zone){
 		widget->appearance.model_type = atoi(row[2]);
 		widget->SetSize(atoi(row[3]));
 		widget->appearance.show_command_icon = atoi(row[4]);
-		widget->SetWidgetID(atoul(row[5]));
+
+		if (row[5] == NULL)
+			widget->SetWidgetID(0xFFFFFFFF);
+		else
+			widget->SetWidgetID(atoul(row[5]));
+
 		widget->SetWidgetX(atof(row[6]));
 		widget->SetWidgetY(atof(row[7]));
 		widget->SetWidgetZ(atof(row[8]));
@@ -4796,7 +4801,7 @@ void WorldDatabase::LoadPlayerStatistics(Player* player, int32 char_id) {
 }
 
 void WorldDatabase::WritePlayerStatistic(Player *player, Statistic* stat) {
-	if (player && stat) {
+	if (player && player->GetCharacterID() > 0 && stat) {
 		Query query;
 		query.RunQuery2(Q_INSERT, "INSERT INTO statistics (char_id, guild_id, stat_id, stat_value, stat_date) VALUES(%i, %i, %i, %i, %i) ON DUPLICATE KEY UPDATE stat_value = %i, stat_date = %i;",
 			player->GetCharacterID(), 0, stat->stat_id, stat->stat_value, stat->stat_date,

+ 4 - 0
EQ2/source/WorldServer/client.cpp

@@ -134,6 +134,7 @@ Client::Client(EQStream* ieqs) : pos_update(125), quest_pos_timer(2000), lua_deb
 	connect->Disable();
 	zoneID = 0;
 	account_name[0] = 0;
+	character_id = 0;
 	account_id = 0;
 	pwaitingforbootup = 0;
 	current_zone = 0;
@@ -3318,6 +3319,9 @@ void Client::DetermineCharacterUpdates ( ) {
 }
 
 void Client::Save(){
+	if (GetCharacterID() == 0)
+		return;
+
 	if(current_zone){
 		DetermineCharacterUpdates();
 

+ 57 - 0
EQ2/source/WorldServer/zoneserver.cpp

@@ -5475,6 +5475,63 @@ void ZoneServer::WritePlayerStatistics() {
 		client_itr->value->GetPlayer()->WritePlayerStatistics();
 }
 
+bool ZoneServer::SendRadiusSpawnInfo(Client* client, float radius) {
+	if (!client)
+		return false;
+
+	Spawn* spawn = 0;
+	bool ret = false;
+	map<int32, Spawn*>::iterator itr;
+	MSpawnList.readlock(__FUNCTION__, __LINE__);
+	for (itr = spawn_list.begin(); itr != spawn_list.end(); itr++) {
+		spawn = itr->second;
+		if (spawn && spawn != client->GetPlayer() && !spawn->IsPlayer() && spawn->GetDistance(client->GetPlayer()) <= radius) {
+			const char* type = "NPC";
+			const char* specialTypeID = "N/A";
+			int32 specialID = 0, spawnEntryID = spawn->GetSpawnEntryID();
+			if (spawn->IsObject())
+			{
+				Object* obj = (Object*)spawn;
+				specialID = obj->GetID();
+				specialTypeID = "GetID";
+				type = "Object";
+			}
+			else if (spawn->IsSign())
+			{
+				Sign* sign = (Sign*)spawn;
+				specialID = sign->GetWidgetID();
+				specialTypeID = "WidgetID";
+				type = "Sign";
+			}
+			else if (spawn->IsWidget())
+			{
+				Widget* widget = (Widget*)spawn;
+				specialID = widget->GetWidgetID();
+				specialTypeID = "WidgetID";
+				if ( specialID == 0xFFFFFFFF )
+					specialTypeID = "WidgetID(spawn_widgets entry missing)";
+
+				type = "Widget";
+			}
+			else if (spawn->IsGroundSpawn())
+			{
+				GroundSpawn* gs = (GroundSpawn*)spawn;
+				specialID = gs->GetGroundSpawnEntryID();
+				specialTypeID = "GroundSpawnEntryID";
+				type = "GroundSpawn";
+			}
+			client->Message(CHANNEL_COLOR_RED, "Name: %s (%s), Spawn Table ID: %u, %s: %u", spawn->GetName(), type, spawn->GetDatabaseID(), specialTypeID, specialID);
+			client->Message(CHANNEL_COLOR_RED, "Spawn Location ID: %u, Spawn Group ID: %u, SpawnEntryID: %u, Grid ID: %u", spawn->GetSpawnLocationID(), spawn->GetSpawnGroupID(), spawnEntryID, spawn->GetLocation());
+			client->Message(CHANNEL_COLOR_RED, "Respawn Time: %u (sec), X: %f, Y: %f, Z: %f Heading: %f", spawn->GetRespawnTime(), spawn->GetX(), spawn->GetY(), spawn->GetZ(), spawn->GetHeading());
+			client->Message(CHANNEL_COLOR_YELLOW, "=============================");
+			ret = true;
+		}
+	}
+	MSpawnList.releasereadlock(__FUNCTION__, __LINE__);
+	return ret;
+}
+
+
 void ZoneServer::AddPlayerTracking(Player* player) {
 	if (player && !player->GetIsTracking() && players_tracking.count(player->GetDatabaseID()) == 0) {
 		Client* client = GetClientBySpawn(player);

+ 2 - 0
EQ2/source/WorldServer/zoneserver.h

@@ -334,6 +334,8 @@ public:
 	
 	void	WritePlayerStatistics();
 	
+	bool	SendRadiusSpawnInfo(Client* client, float radius);
+
 	volatile bool	spawnthread_active;
 	volatile bool	combatthread_active;
 	volatile int8	initial_spawn_threads_active;

+ 29 - 0
EQ2/source/common/database.cpp

@@ -213,6 +213,35 @@ MYSQL_RES* Query::RunQuery2(string in_query, QUERY_TYPE type){
 		multiple_results->push_back(result);
 	}	
 	query = in_query;
+
+#ifdef WORLD && _DEBUG
+	if (type == Q_UPDATE || type == Q_INSERT || type == Q_DELETE || type == Q_REPLACE)
+	{
+		char* filteredTables[] = { " characters", " character_", " statistics", " variables", " guilds" };
+
+		bool match = false;
+		for (int i = 0; i < sizeof(filteredTables) / sizeof(filteredTables[0]); i++)
+		{
+			if (query.find(filteredTables[i]) != std::string::npos) {
+				match = true;
+			}
+		}
+		try
+		{
+			if (!match)
+			{
+				FILE* pFile;
+				pFile = fopen("sql_updates.sql", "a+");
+				fwrite(query.c_str(), 1, query.length(), pFile);
+				fwrite("\n", sizeof(char), 1, pFile);
+				fclose(pFile);
+			}
+		}
+		catch (...) {}
+	}
+#endif
+
+	
 	database.RunQuery(query.c_str(), query.length(), errbuf, &result, affected_rows, last_insert_id, &errnum, retry); 
 	return result;
 }