#include "../common/global_define.h" #include "../common/emu_tcp_connection.h" #include "../common/eqemu_logsys.h" #include "../common/md5.h" #include "../common/packet_dump.h" #include "../common/packet_functions.h" #include "../common/servertalk.h" #include "../common/web_interface_utils.h" #include "client.h" #include "entity.h" #include "mob.h" #include "npc.h" #include "quest_parser_collection.h" #include "remote_call.h" #include "remote_call_subscribe.h" #include "worldserver.h" #include "zone.h" #include std::map remote_call_methods; extern WorldServer worldserver; extern Zone* zone; void RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::map &res, const std::string &error) { uint32 sz = (uint32)(connection_id.size() + request_id.size() + error.size() + 3 + 16); auto iter = res.begin(); while(iter != res.end()) { sz += (uint32)iter->first.size() + (uint32)iter->second.size() + 10; ++iter; } ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCallResponse, sz); pack->WriteUInt32((uint32)request_id.size()); pack->WriteString(request_id.c_str()); pack->WriteUInt32((uint32)connection_id.size()); pack->WriteString(connection_id.c_str()); pack->WriteUInt32((uint32)error.size()); pack->WriteString(error.c_str()); pack->WriteUInt32((uint32)res.size()); iter = res.begin(); while(iter != res.end()) { pack->WriteUInt32((uint32)iter->first.size()); pack->WriteString(iter->first.c_str()); pack->WriteUInt32((uint32)iter->second.size()); pack->WriteString(iter->second.c_str()); ++iter; } worldserver.SendPacket(pack); safe_delete(pack); } void RemoteCall(const std::string &connection_id, const std::string &method, const std::vector ¶ms) { uint32 sz = (uint32)(connection_id.size() + method.size() + 14); auto iter = params.begin(); while(iter != params.end()) { sz += (uint32)iter->size() + 5; ++iter; } ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCallToClient, sz); pack->WriteUInt32((uint32)connection_id.size()); pack->WriteString(connection_id.c_str()); pack->WriteUInt32((uint32)method.size()); pack->WriteString(method.c_str()); pack->WriteUInt32((uint32)params.size()); iter = params.begin(); while(iter != params.end()) { pack->WriteUInt32((uint32)iter->size()); pack->WriteString(iter->c_str()); ++iter; } worldserver.SendPacket(pack); safe_delete(pack); } /* Zone: register_remote_call_handlers */ void register_remote_call_handlers() { remote_call_methods["Zone.Action"] = handle_rc_zone_action; remote_call_methods["Zone.GetEntityAttributes"] = handle_rc_get_entity_attributes; remote_call_methods["Zone.GetInitialEntityPositions"] = handle_rc_get_initial_entity_positions; remote_call_methods["Zone.MoveEntity"] = handle_rc_move_entity; remote_call_methods["Zone.SetEntityAttribute"] = handle_rc_set_entity_attribute; remote_call_methods["Zone.Subscribe"] = handle_rc_subscribe; remote_call_methods["Zone.Unsubscribe"] = handle_rc_unsubscribe; } void handle_rc_subscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; if(params.size() != 1) { error = "Missing event to subscribe to"; RemoteCallResponse(connection_id, request_id, res, error); return; } if(RemoteCallSubscriptionHandler::Instance()->Subscribe(connection_id, params[0])) { res["status"] = "subscribed"; } else { res["status"] = "failed to subscribe"; } RemoteCallResponse(connection_id, request_id, res, error); } void handle_rc_unsubscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; if(params.size() != 1) { error = "Missing event to unsubscribe from"; RemoteCallResponse(connection_id, request_id, res, error); return; } if(RemoteCallSubscriptionHandler::Instance()->Subscribe(connection_id, params[0])) { res["status"] = "unsubscribed"; } else { res["status"] = "failed to unsubscribe"; } RemoteCallResponse(connection_id, request_id, res, error); } void handle_rc_get_initial_entity_positions(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; std::list npc_list; entity_list.GetNPCList(npc_list); for(std::list::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) { NPC* npc = *itr; res["ent_id"] = std::to_string((long)npc->GetID()); res["race_id"] = std::to_string((long)npc->GetRace()); res["class_id"] = std::to_string((long)npc->GetClass()); res["type"] = "NPC"; res["name"] = npc->GetCleanName(); res["x"] = std::to_string((double)npc->GetX()); res["y"] = std::to_string((double)npc->GetY()); res["z"] = std::to_string((double)npc->GetZ()); res["h"] = std::to_string((double)npc->GetHeading()); res["aggro_range"] = std::to_string((double)npc->GetAggroRange()); res["gender"] = std::to_string((double)npc->GetGender()); RemoteCallResponse(connection_id, request_id, res, error); } std::list client_list; entity_list.GetClientList(client_list); for (std::list::iterator itr = client_list.begin(); itr != client_list.end(); ++itr) { Client* c = *itr; res["ent_id"] = itoa(c->GetID()); res["race_id"] = std::to_string((long)c->GetRace()); res["class_id"] = std::to_string((long)c->GetClass()); res["type"] = "Client"; res["name"] = c->GetCleanName(); res["x"] = itoa(c->GetX()); res["y"] = itoa(c->GetY()); res["z"] = itoa(c->GetZ()); res["h"] = itoa(c->GetHeading()); RemoteCallResponse(connection_id, request_id, res, error); } std::list corpse_list; entity_list.GetCorpseList(corpse_list); for (std::list::iterator itr = corpse_list.begin(); itr != corpse_list.end(); ++itr) { Corpse* c = *itr; res["ent_id"] = itoa(c->GetID()); res["race_id"] = std::to_string((long)c->GetRace()); res["class_id"] = std::to_string((long)c->GetClass()); res["type"] = "Corpse"; res["name"] = c->GetCleanName(); res["x"] = itoa(c->GetX()); res["y"] = itoa(c->GetY()); res["z"] = itoa(c->GetZ()); res["h"] = itoa(c->GetHeading()); RemoteCallResponse(connection_id, request_id, res, error); } std::list door_list; entity_list.GetDoorsList(door_list); for (std::list::iterator itr = door_list.begin(); itr != door_list.end(); ++itr) { Doors* c = *itr; res["ent_id"] = itoa(c->GetEntityID()); res["type"] = "Door"; res["name"] = c->GetDoorName(); res["x"] = itoa(c->GetPosition().x); res["y"] = itoa(c->GetPosition().y); res["z"] = itoa(c->GetPosition().z); res["h"] = itoa(c->GetPosition().w); RemoteCallResponse(connection_id, request_id, res, error); } std::list object_list; entity_list.GetObjectList(object_list); for (std::list::iterator itr = object_list.begin(); itr != object_list.end(); ++itr) { Object* c = *itr; res["ent_id"] = itoa(c->GetID()); res["type"] = "Object"; res["name"] = c->GetModelName(); res["x"] = itoa(c->GetX()); res["y"] = itoa(c->GetY()); res["z"] = itoa(c->GetZ()); res["h"] = itoa(c->GetHeadingData()); RemoteCallResponse(connection_id, request_id, res, error); } } void handle_rc_move_entity(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; if (params.size() != 5) { error = "Missing function data"; std::cout << error << "\n" << std::endl; RemoteCallResponse(connection_id, request_id, res, error); return; } /* 0 = Ent ID, 1 = X, 2 = Y, 3 = Z, 4 = H */ Mob *ent = entity_list.GetMob(atoi(params[0].c_str())); if (ent){ if (ent->IsClient()){ ent->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), atoi(params[1].c_str()), atoi(params[2].c_str()), ent->GetGroundZ(atoi(params[1].c_str()), atoi(params[2].c_str())), ent->GetHeading()); } else{ ent->GMMove(atoi(params[1].c_str()), atoi(params[2].c_str()), ent->GetGroundZ(atoi(params[1].c_str()), atoi(params[2].c_str())), ent->GetHeading()); } } } void handle_rc_zone_action(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; /* Zone Reload Functions */ if (params[0] == "Repop") { zone->Repop(); } if (params[0] == "RepopForce") { zone->Repop(); //LinkedListIterator iterator(zone->spawn2_list); //iterator.Reset(); //while (iterator.MoreElements()) { // std::string query = StringFormat( // "DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu", // (unsigned long)iterator.GetData()->GetID(), // (unsigned long)zone->GetInstanceID() // ); // auto results = database.QueryDatabase(query); // iterator.Advance(); //} } if (params[0] == "ReloadQuests"){ parse->ReloadQuests(); } /* Zone Visuals Functions */ if (params[0] == "ZoneSky"){ for (int z = 0; z < 4; z++) { zone->newzone_data.fog_red[z] = atoi(params[1].c_str()); zone->newzone_data.fog_green[z] = atoi(params[2].c_str()); zone->newzone_data.fog_blue[z] = atoi(params[3].c_str()); zone->newzone_data.sky = 0; } EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); } if (params[0] == "ZoneFogDensity"){ zone->newzone_data.fog_density = atof(params[1].c_str()); EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); } if (params[0] == "ZoneFogClip"){ for (int z = 0; z < 4; z++) { zone->newzone_data.fog_minclip[z] = atoi(params[1].c_str()); zone->newzone_data.fog_maxclip[z] = atoi(params[2].c_str()); zone->newzone_data.sky = 0; } EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); } if (params[0] == "ZoneClip"){ zone->newzone_data.minclip = atoi(params[1].c_str()); zone->newzone_data.maxclip = atoi(params[2].c_str()); EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); } if (params[0] == "ZoneSaveHeaders"){ zone->SaveZoneCFG(); } if (params[0] == "Kill"){ Mob *ent = entity_list.GetMob(atoi(params[1].c_str())); if (ent){ ent->Kill(); } } if (params[0] == "Broadcast") { worldserver.SendEmoteMessage(0, 0, 15, "God Broadcasts: %s", params[1].c_str()); } if (params[0] == "Shout") { entity_list.Message(0, 13, "God shouts, '%s'", params[1].c_str()); } if (params[0] == "EntitySay") { Mob *ent = entity_list.GetMob(atoi(params[1].c_str())); if (ent) { ent->Say(params[2].c_str()); } } if (params[0] == "EntityShout") { Mob *ent = entity_list.GetMob(atoi(params[1].c_str())); if (ent) { ent->Shout(params[2].c_str()); } } } /* Server -> Client */ void handle_rc_get_entity_attributes(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; if (params.size() != 1) { error = "Missing function data"; std::cout << error << "\n" << std::endl; RemoteCallResponse(connection_id, request_id, res, error); return; } Mob *ent = entity_list.GetMob(atoi(params[0].c_str())); if (ent){ res["ent_id"] = itoa(ent->GetID()); res["clean_name"] = ent->GetCleanName(); res["name"] = ent->GetName(); res["race"] = itoa(ent->GetRace()); res["class"] = itoa(ent->GetClass()); res["size"] = itoa(ent->GetSize()); res["texture"] = itoa(ent->GetTexture()); res["gender"] = itoa(ent->GetGender()); res["weapon_1"] = itoa(ent->GetEquipmentMaterial(7)); res["weapon_2"] = itoa(ent->GetEquipmentMaterial(8)); res["heading"] = itoa(ent->GetHeading()); RemoteCallResponse(connection_id, request_id, res, error); } } /* Client -> Server :: Zone.SetEntityAttribute */ void handle_rc_set_entity_attribute(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; if (params.size() != 3) { error = "Missing function data"; std::cout << error << "\n" << std::endl; RemoteCallResponse(connection_id, request_id, res, error); return; } Mob *ent = entity_list.GetMob(atoi(params[0].c_str())); if (ent){ if (params[1] == "race"){ ent->SendIllusionPacket(atoi(params[2].c_str())); } if (params[1] == "appearance_effect"){ ent->SendAppearanceEffect(atoi(params[2].c_str()), 0, 0, 0, 0); } if (params[1] == "size"){ ent->ChangeSize(atoi(params[2].c_str())); } if (params[1] == "texture"){ ent->SendIllusionPacket(0, 0xFF, atoi(params[2].c_str()), 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0); } if (params[1] == "gender"){ ent->SendIllusionPacket(0, atoi(params[2].c_str()), 0xFF, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0); } if (params[1] == "weapon_1"){ ent->WearChange(7, atoi(params[2].c_str()), 0); } if (params[1] == "weapon_2"){ ent->WearChange(8, atoi(params[2].c_str()), 0); } if (params[1] == "heading"){ ent->GMMove(ent->GetX(), ent->GetY(), ent->GetZ(), atoi(params[2].c_str()), true); } } }