1
0

Added public zone persistence of spawns back, command /location list respawns added, additionally added tracking of duplicate zones for exceeding player limits

This commit is contained in:
Emagi 2024-12-15 15:22:21 -05:00
parent 92b8e406e3
commit fe10353863
10 changed files with 113 additions and 36 deletions

View File

@ -7510,7 +7510,7 @@ void Commands::Command_Location(Client* client)
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location add [location id]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location add [location id]");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location remove [location point id]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location remove [location point id]");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location delete [location id]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location delete [location id]");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location list [locations|points] [location id if points used]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/location list [locations|points|respawns] [location id if points used]");
} }
/* /*
@ -7603,16 +7603,18 @@ void Commands::Command_LocationList(Client* client, Seperator* sep)
if (strncmp(option, "locations", strlen(option)) == 0) if (strncmp(option, "locations", strlen(option)) == 0)
database.ListLocations(client); database.ListLocations(client);
else if (strncmp(option, "respawns", strlen(option)) == 0)
client->GetPlayer()->GetZone()->SendRespawnTimerList(client);
else if (strncmp(option, "points", strlen(option)) == 0 && sep->arg[1] && sep->IsNumber(1)) else if (strncmp(option, "points", strlen(option)) == 0 && sep->arg[1] && sep->IsNumber(1))
{ {
int32 location_id = atoul(sep->arg[1]); int32 location_id = atoul(sep->arg[1]);
database.ListLocationPoints(client, location_id); database.ListLocationPoints(client, location_id);
} }
else else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Useage: /location list [locations|points] [location ID if points used]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Useage: /location list [locations|points|respawns] [location ID if points used]");
} }
else else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Useage: /location list [locations|points] [location ID if points used]"); client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Useage: /location list [locations|points|respawns] [location ID if points used]");
} }
/* /*
@ -10991,6 +10993,9 @@ void Commands::Command_Test(Client* client, EQ2_16BitString* command_parms) {
guild->SendGuildMemberList(); guild->SendGuildMemberList();
} }
else if(atoi(sep->arg[0]) == 38) {
client->GetPlayer()->GetZone()->SendFlightPathsPackets(client);
}
} }
else { else {
PacketStruct* packet2 = configReader.getStruct("WS_ExaminePartialSpellInfo", client->GetVersion()); PacketStruct* packet2 = configReader.getStruct("WS_ExaminePartialSpellInfo", client->GetVersion());

View File

@ -1905,7 +1905,7 @@ bool PlayerGroupManager::IdentifyMemberInGroupOrRaid(ZoneChangeDetails* details,
tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(),
tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers()); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone());
safe_delete(tmp); safe_delete(tmp);
succeed = true; succeed = true;
break; break;
@ -1922,7 +1922,7 @@ bool PlayerGroupManager::IdentifyMemberInGroupOrRaid(ZoneChangeDetails* details,
ret->GetSafeZ(), ret->GetSafeHeading(), ret->GetZoneLockState(), ret->GetSafeZ(), ret->GetSafeHeading(), ret->GetZoneLockState(),
ret->GetMinimumStatus(), ret->GetMinimumLevel(), ret->GetMaximumLevel(), ret->GetMinimumStatus(), ret->GetMinimumLevel(), ret->GetMaximumLevel(),
ret->GetMinimumVersion(), ret->GetDefaultLockoutTime(), ret->GetDefaultReenterTime(), ret->GetMinimumVersion(), ret->GetDefaultLockoutTime(), ret->GetDefaultReenterTime(),
ret->GetInstanceType(), ret->NumPlayers(), ret); ret->GetInstanceType(), ret->NumPlayers(), ret->IsCityZone(), ret);
return true; return true;
} }
@ -1946,7 +1946,7 @@ bool PlayerGroupManager::IdentifyMemberInGroupOrRaid(ZoneChangeDetails* details,
tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(),
tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers()); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone());
safe_delete(tmp); safe_delete(tmp);
succeed = true; succeed = true;
break; break;

View File

@ -96,7 +96,7 @@ void PeerManager::updateClientTree(const std::string& id, const boost::property_
void PeerManager::setZonePeerData(ZoneChangeDetails* opt_details, std::string peerId, std::string peerWorldAddress, std::string peerInternalWorldAddress, int16 peerWorldPort, void PeerManager::setZonePeerData(ZoneChangeDetails* opt_details, std::string peerId, std::string peerWorldAddress, std::string peerInternalWorldAddress, int16 peerWorldPort,
std::string peerWebAddress, int16 peerWebPort, std::string zoneFileName, std::string peerWebAddress, int16 peerWebPort, std::string zoneFileName,
std::string zoneName, int32 zoneId, int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus, std::string zoneName, int32 zoneId, int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus,
int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers) { int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers, bool isCityZone) {
if (opt_details) { if (opt_details) {
opt_details->peerId = peerId; opt_details->peerId = peerId;
opt_details->peerWorldAddress = peerWorldAddress; opt_details->peerWorldAddress = peerWorldAddress;
@ -122,6 +122,7 @@ void PeerManager::setZonePeerData(ZoneChangeDetails* opt_details, std::string pe
opt_details->defaultReenterTime = defaultReenterTime; opt_details->defaultReenterTime = defaultReenterTime;
opt_details->instanceType = instanceType; opt_details->instanceType = instanceType;
opt_details->numPlayers = numPlayers; opt_details->numPlayers = numPlayers;
opt_details->isCityZone = isCityZone;
opt_details->zonePtr = nullptr; opt_details->zonePtr = nullptr;
opt_details->peerAuthorized = false; opt_details->peerAuthorized = false;
opt_details->zoneKey = 0; opt_details->zoneKey = 0;
@ -133,7 +134,7 @@ void PeerManager::setZonePeerData(ZoneChangeDetails* opt_details, std::string pe
void PeerManager::setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::string zoneFileName, std::string zoneName, int32 zoneId, void PeerManager::setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::string zoneFileName, std::string zoneName, int32 zoneId,
int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus, int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus,
int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType,
int32 numPlayers, void* zonePtr) { int32 numPlayers, bool isCityZone, void* zonePtr) {
if (opt_details) { if (opt_details) {
opt_details->peerId = "self"; opt_details->peerId = "self";
opt_details->peerWorldAddress = net.GetWorldAddress(); opt_details->peerWorldAddress = net.GetWorldAddress();
@ -158,6 +159,7 @@ void PeerManager::setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::strin
opt_details->defaultReenterTime = defaultReenterTime; opt_details->defaultReenterTime = defaultReenterTime;
opt_details->instanceType = instanceType; opt_details->instanceType = instanceType;
opt_details->numPlayers = numPlayers; opt_details->numPlayers = numPlayers;
opt_details->isCityZone = isCityZone;
opt_details->zonePtr = zonePtr; opt_details->zonePtr = zonePtr;
opt_details->peerAuthorized = true; opt_details->peerAuthorized = true;
opt_details->zoneKey = 0; opt_details->zoneKey = 0;
@ -167,6 +169,8 @@ void PeerManager::setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::strin
} }
std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 inc_zone_id, int32 inc_instance_id, ZoneChangeDetails* opt_details, bool only_always_loaded) { std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 inc_zone_id, int32 inc_instance_id, ZoneChangeDetails* opt_details, bool only_always_loaded) {
bool matchFullZone = false;
std::string fullZoneId = "";
for (auto& [peerId, peer] : peers) { for (auto& [peerId, peer] : peers) {
if (peer->healthCheck.status != HealthStatus::OK) if (peer->healthCheck.status != HealthStatus::OK)
continue; continue;
@ -211,9 +215,17 @@ std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 i
match = true; match = true;
} }
if(!instance_zone && num_players >= 30 && !city_zone) {
match = false;
setZonePeerData(opt_details, peerId, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, zone_file_name, zone_name, zone_id, instance_id,
safe_x, safe_y, safe_z, safe_heading, lock_state, min_status, min_level, max_level, min_version, default_lockout_time, default_reenter_time, instance_type, num_players, city_zone);
matchFullZone = true;
fullZoneId = peerId;
}
if (match) { if (match) {
setZonePeerData(opt_details, peerId, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, zone_file_name, zone_name, zone_id, instance_id, setZonePeerData(opt_details, peerId, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, zone_file_name, zone_name, zone_id, instance_id,
safe_x, safe_y, safe_z, safe_heading, lock_state, min_status, min_level, max_level, min_version, default_lockout_time, default_reenter_time, instance_type, num_players); safe_x, safe_y, safe_z, safe_heading, lock_state, min_status, min_level, max_level, min_version, default_lockout_time, default_reenter_time, instance_type, num_players, city_zone);
return peerId; return peerId;
} }
} }
@ -223,7 +235,8 @@ std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 i
LogWrite(PEERING__ERROR, 0, "Peering", "%s: Error Parsing Zones for %s:%u", __FUNCTION__, peer->webAddr.c_str(), peer->webPort); LogWrite(PEERING__ERROR, 0, "Peering", "%s: Error Parsing Zones for %s:%u", __FUNCTION__, peer->webAddr.c_str(), peer->webPort);
} }
} }
return "";
return fullZoneId;
} }
void PeerManager::handlePrimaryConflict(const std::string& reconnectingPeerId) { void PeerManager::handlePrimaryConflict(const std::string& reconnectingPeerId) {

View File

@ -87,6 +87,7 @@ struct ZoneChangeDetails {
int32 defaultReenterTime; int32 defaultReenterTime;
int8 instanceType; int8 instanceType;
int32 numPlayers; int32 numPlayers;
bool isCityZone;
void* zonePtr; void* zonePtr;
bool peerAuthorized; bool peerAuthorized;
int32 zoneKey; int32 zoneKey;
@ -171,10 +172,10 @@ public:
void setZonePeerData(ZoneChangeDetails* opt_details, std::string peerId, std::string peerWorldAddress, std::string peerInternalWorldAddress, int16 peerWorldPort, void setZonePeerData(ZoneChangeDetails* opt_details, std::string peerId, std::string peerWorldAddress, std::string peerInternalWorldAddress, int16 peerWorldPort,
std::string peerWebAddress, int16 peerWebPort, std::string zoneFileName, std::string zoneName, int32 zoneId, std::string peerWebAddress, int16 peerWebPort, std::string zoneFileName, std::string zoneName, int32 zoneId,
int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus, int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus,
int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers); int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers, bool isCityZone);
void setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::string zoneFileName, std::string zoneName, int32 zoneId, void setZonePeerDataSelf(ZoneChangeDetails* opt_details, std::string zoneFileName, std::string zoneName, int32 zoneId,
int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus, int32 instanceId, float safeX, float safeY, float safeZ, float safeHeading, bool lockState, sint16 minStatus,
int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers, void* zonePtr = nullptr); int16 minLevel, int16 maxLevel, int16 minVersion, int32 defaultLockoutTime, int32 defaultReenterTime, int8 instanceType, int32 numPlayers, bool isCityZone, void* zonePtr = nullptr);
bool IsClientConnectedPeer(int32 account_id); bool IsClientConnectedPeer(int32 account_id);
std::string GetCharacterPeerId(std::string charName); std::string GetCharacterPeerId(std::string charName);
void SendPeersChannelMessage(int32 group_id, std::string fromName, std::string message, int16 channel, int32 language_id = 0); void SendPeersChannelMessage(int32 group_id, std::string fromName, std::string message, int16 channel, int32 language_id = 0);

View File

@ -503,6 +503,7 @@ void ZoneList::PopulateZoneList(boost::property_tree::ptree& pt) {
zone_pt.put("default_reenter_time", tmp->GetDefaultReenterTime()); zone_pt.put("default_reenter_time", tmp->GetDefaultReenterTime());
zone_pt.put("instance_type", static_cast<int8>(tmp->GetInstanceType())); zone_pt.put("instance_type", static_cast<int8>(tmp->GetInstanceType()));
zone_pt.put("always_loaded", tmp->AlwaysLoaded()); zone_pt.put("always_loaded", tmp->AlwaysLoaded());
zone_pt.put("duplicated_zone", tmp->DuplicatedZone());
maintree.push_back(std::make_pair("", zone_pt)); maintree.push_back(std::make_pair("", zone_pt));
} }
@ -627,7 +628,7 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
int32 instanceId = 0; int32 instanceId = 0;
int32 zoneId = 0; int32 zoneId = 0;
std::string zoneName(""); std::string zoneName("");
bool alwaysLoaded = false; bool alwaysLoaded = false, duplicatedZone = false;
int32 minLevel = 0, maxLevel = 0, avgLevel = 0, firstLevel = 0; int32 minLevel = 0, maxLevel = 0, avgLevel = 0, firstLevel = 0;
if (auto inst_id = json_tree.get_optional<int32>("instance_id")) { if (auto inst_id = json_tree.get_optional<int32>("instance_id")) {
instanceId = inst_id.get(); instanceId = inst_id.get();
@ -645,6 +646,10 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
alwaysLoaded = always_loaded.get(); alwaysLoaded = always_loaded.get();
} }
if (auto duplicated_zone = json_tree.get_optional<bool>("duplicated_zone")) {
duplicatedZone = duplicated_zone.get();
}
if (auto level = json_tree.get_optional<int32>("min_level")) { if (auto level = json_tree.get_optional<int32>("min_level")) {
minLevel = level.get(); minLevel = level.get();
} }
@ -665,8 +670,12 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
ZoneChangeDetails details; ZoneChangeDetails details;
if (instanceId || zoneId || zoneName.length() > 0) { if (instanceId || zoneId || zoneName.length() > 0) {
if (!instanceId) { if (!instanceId) {
if ((zone_list.GetZone(&details, zoneId, zoneName, true, false, false, false, false, alwaysLoaded))) if ((zone_list.GetZone(&details, zoneId, zoneName, true, false, false, false, false, alwaysLoaded, false, duplicatedZone))) {
if(details.zonePtr) {
((ZoneServer*)details.zonePtr)->SetDuplicatedZone(duplicatedZone);
}
success = 1; success = 1;
}
} }
else { else {
if ((zone_list.GetZoneByInstance(&details, instanceId, zoneId, true, false, false, false, minLevel, maxLevel, avgLevel, firstLevel))) if ((zone_list.GetZoneByInstance(&details, instanceId, zoneId, true, false, false, false, minLevel, maxLevel, avgLevel, firstLevel)))

View File

@ -686,10 +686,11 @@ void ZoneList::Remove(ZoneServer* zone) {
} }
} }
bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::string opt_zone_name, bool loadZone, bool skip_existing_zones, bool increment_zone, bool check_peers, bool check_instances, bool only_always_loaded, bool skip_self, int32 minLevel, int32 maxLevel, int32 avgLevel, int32 firstLevel) { bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::string opt_zone_name, bool loadZone, bool skip_existing_zones, bool increment_zone, bool check_peers, bool check_instances, bool only_always_loaded, bool skip_self, bool duplicated_zone, int32 minLevel, int32 maxLevel, int32 avgLevel, int32 firstLevel) {
list<ZoneServer*>::iterator zone_iter; list<ZoneServer*>::iterator zone_iter;
ZoneServer* tmp = 0; ZoneServer* tmp = 0;
ZoneServer* ret = 0; ZoneServer* ret = 0;
bool hadFullZone = false;
if(!skip_existing_zones) { if(!skip_existing_zones) {
if(!skip_self) { if(!skip_self) {
MZoneList.readlock(__FUNCTION__, __LINE__); MZoneList.readlock(__FUNCTION__, __LINE__);
@ -706,6 +707,9 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
} }
break; break;
} }
else if(!tmp->IsCityZone()) {
hadFullZone = true;
}
} }
} }
tmp = nullptr; tmp = nullptr;
@ -715,8 +719,15 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
if(!ret && check_peers) { if(!ret && check_peers) {
std::string peerId = peer_manager.getZonePeerId(opt_zone_name, opt_zone_id, 0, zone_details, only_always_loaded); std::string peerId = peer_manager.getZonePeerId(opt_zone_name, opt_zone_id, 0, zone_details, only_always_loaded);
if(peerId.size() > 0) { if(peerId.size() > 0) {
LogWrite(WORLD__ERROR, 0, "World", "Peer %s is providing zone %s for zone %s id %u", peerId.c_str(), zone_details->zoneName.c_str(), opt_zone_name.c_str(), opt_zone_id);
return true; if(zone_details->instanceType == 0 && zone_details->numPlayers >= 30 && !zone_details->isCityZone) {
LogWrite(WORLD__WARNING, 0, "World", "Peer %s is providing zone %s for zone %s id %u, however the zone is full, omitting result.", peerId.c_str(), zone_details->zoneName.c_str(), opt_zone_name.c_str(), opt_zone_id);
hadFullZone = true;
}
else {
LogWrite(WORLD__INFO, 0, "World", "Peer %s is providing zone %s for zone %s id %u", peerId.c_str(), zone_details->zoneName.c_str(), opt_zone_name.c_str(), opt_zone_id);
return true;
}
} }
} }
} }
@ -738,6 +749,7 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
root.put("zone_name", opt_zone_name); root.put("zone_name", opt_zone_name);
root.put("zone_id", std::to_string(opt_zone_id)); root.put("zone_id", std::to_string(opt_zone_id));
root.put("always_loaded", only_always_loaded); root.put("always_loaded", only_always_loaded);
root.put("duplicated_zone", hadFullZone);
root.put("min_level", minLevel); root.put("min_level", minLevel);
root.put("max_level", maxLevel); root.put("max_level", maxLevel);
@ -746,19 +758,20 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
std::ostringstream jsonStream; std::ostringstream jsonStream;
boost::property_tree::write_json(jsonStream, root); boost::property_tree::write_json(jsonStream, root);
std::string jsonPayload = jsonStream.str(); std::string jsonPayload = jsonStream.str();
LogWrite(PEERING__DEBUG, 0, "Peering", "%s: Notify Peer %s StartZone %s (%u), always loaded %u", __FUNCTION__, peer->id.c_str(), opt_zone_name.c_str(), opt_zone_id, only_always_loaded); LogWrite(PEERING__DEBUG, 0, "Peering", "%s: Notify Peer %s StartZone %s (%u), always loaded %u, had full zone %%u", __FUNCTION__, peer->id.c_str(), opt_zone_name.c_str(), opt_zone_id, only_always_loaded, hadFullZone);
peer_https_pool.sendPostRequestToPeerAsync(peer->id, peer->webAddr, std::to_string(peer->webPort), "/startzone", jsonPayload); peer_https_pool.sendPostRequestToPeerAsync(peer->id, peer->webAddr, std::to_string(peer->webPort), "/startzone", jsonPayload);
peer_manager.setZonePeerData(zone_details, peer->id, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, std::string(tmp->GetZoneFile()), std::string(tmp->GetZoneName()), tmp->GetZoneID(), peer_manager.setZonePeerData(zone_details, peer->id, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, std::string(tmp->GetZoneFile()), std::string(tmp->GetZoneName()), tmp->GetZoneID(),
tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(),
tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers()); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone());
safe_delete(tmp); safe_delete(tmp);
return true; return true;
} }
else { else {
tmp = new ZoneServer(opt_zone_name.c_str()); tmp = new ZoneServer(opt_zone_name.c_str());
database.LoadZoneInfo(tmp, minLevel, maxLevel, avgLevel, firstLevel); database.LoadZoneInfo(tmp, minLevel, maxLevel, avgLevel, firstLevel);
tmp->SetDuplicatedZone(hadFullZone);
tmp->Init(); tmp->Init();
tmp->SetAlwaysLoaded(only_always_loaded); tmp->SetAlwaysLoaded(only_always_loaded);
} }
@ -770,7 +783,7 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(),
tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers(), tmp); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone(), tmp);
if(zone_details) { if(zone_details) {
zone_details->zonePtr = (void*)tmp; zone_details->zonePtr = (void*)tmp;
} }
@ -837,7 +850,7 @@ bool ZoneList::GetZoneByInstance(ZoneChangeDetails* zone_details, int32 instance
instance_id, tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), instance_id, tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetMaximumLevel(),
tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers()); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone());
safe_delete(tmp); safe_delete(tmp);
return true; return true;
} }
@ -858,7 +871,7 @@ bool ZoneList::GetZoneByInstance(ZoneChangeDetails* zone_details, int32 instance
tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(), tmp->GetInstanceID(), tmp->GetSafeX(), tmp->GetSafeY(), tmp->GetSafeZ(), tmp->GetSafeHeading(),
tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(), tmp->GetZoneLockState(), tmp->GetMinimumStatus(), tmp->GetMinimumLevel(),
tmp->GetMaximumLevel(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(), tmp->GetMaximumLevel(), tmp->GetMinimumVersion(), tmp->GetDefaultLockoutTime(), tmp->GetDefaultReenterTime(),
tmp->GetInstanceType(), tmp->NumPlayers(), tmp); tmp->GetInstanceType(), tmp->NumPlayers(), tmp->IsCityZone(), tmp);
zone_details->zonePtr = (void*)tmp; zone_details->zonePtr = (void*)tmp;
} }
return (tmp != nullptr) ? true : false; return (tmp != nullptr) ? true : false;
@ -1010,9 +1023,10 @@ void PeerManager::sendZonePeerList(Client* client) {
int32 default_lockout_time = zone.second.get<int32>("default_lockout_time"); int32 default_lockout_time = zone.second.get<int32>("default_lockout_time");
int32 default_reenter_time = zone.second.get<int32>("default_reenter_time"); int32 default_reenter_time = zone.second.get<int32>("default_reenter_time");
int8 instance_type = zone.second.get<int8>("instance_type"); int8 instance_type = zone.second.get<int8>("instance_type");
bool duplicated_zone = zone.second.get<std::string>("duplicated_zone") == "true";
client->Message(CHANNEL_COLOR_YELLOW,"Zone (ID) (InstanceID): %s (%u) (%u), Peer: %s, NumPlayers: %u, Locked: %s, ShuttingDown: %s.",zone_name.c_str(),zone_id, client->Message(CHANNEL_COLOR_YELLOW,"Zone (ID) (InstanceID): %s (%u) (%u), Peer: %s, NumPlayers: %u, Locked: %s, ShuttingDown: %s, DuplicateZone: %s.",zone_name.c_str(),zone_id,
instance_id,peer->id.c_str(), num_players, lock_state ? "true" : "false", shutting_down ? "true" : "false"); instance_id,peer->id.c_str(), num_players, lock_state ? "true" : "false", shutting_down ? "true" : "false", duplicated_zone ? "true" : "false");
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
LogWrite(PEERING__ERROR, 0, "Peering", "%s: Zones Parsing Error %s for %s:%u/%s", __FUNCTION__, e.what() ? e.what() : "??", peer->webAddr.c_str(), peer->webPort); LogWrite(PEERING__ERROR, 0, "Peering", "%s: Zones Parsing Error %s for %s:%u/%s", __FUNCTION__, e.what() ? e.what() : "??", peer->webAddr.c_str(), peer->webPort);

View File

@ -419,7 +419,7 @@ class ZoneList {
void Add(ZoneServer* zone); void Add(ZoneServer* zone);
void Remove(ZoneServer* zone); void Remove(ZoneServer* zone);
bool GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::string opt_zone_name = "", bool loadZone = true, bool skip_existing_zones = false, bool increment_zone = true, bool check_peers = true, bool check_instances = false, bool only_always_loaded = false, bool skip_self = false, int32 minLevel = 0, int32 maxLevel = 0, int32 avgLevel = 0, int32 firstLevel = 0); bool GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::string opt_zone_name = "", bool loadZone = true, bool skip_existing_zones = false, bool increment_zone = true, bool check_peers = true, bool check_instances = false, bool only_always_loaded = false, bool skip_self = false, bool duplicated_zone = false, int32 minLevel = 0, int32 maxLevel = 0, int32 avgLevel = 0, int32 firstLevel = 0);
bool GetZoneByInstance(ZoneChangeDetails* zone_details, int32 instance_id, int32 zone_id = 0, bool loadZone = true, bool skip_existing_zones = false, bool increment_zone = true, bool check_peers = true, int32 minLevel = 0, int32 maxLevel = 0, int32 avgLevel = 0, int32 firstLevel = 0); bool GetZoneByInstance(ZoneChangeDetails* zone_details, int32 instance_id, int32 zone_id = 0, bool loadZone = true, bool skip_existing_zones = false, bool increment_zone = true, bool check_peers = true, int32 minLevel = 0, int32 maxLevel = 0, int32 avgLevel = 0, int32 firstLevel = 0);
bool IsClientConnectedPeer(int32 account_id); bool IsClientConnectedPeer(int32 account_id);

View File

@ -6138,11 +6138,16 @@ map<int32,int32>* WorldDatabase::GetPersistedSpawns(int32 zone_id, int8 type)
LogWrite(SPAWN__TRACE, 1, "Spawn", "Enter %s", __FUNCTION__); LogWrite(SPAWN__TRACE, 1, "Spawn", "Enter %s", __FUNCTION__);
LogWrite(INSTANCE__DEBUG, 0, "Instance", "Loading persisted spawns for zone_id: %u, spawn_type: %u", zone_id, type); LogWrite(ZONE__DEBUG, 0, "Zone", "Loading persisted spawns for zone_id: %u, spawn_type: %u", zone_id, type);
if( !database_new.Select(&result, "SELECT spawn_location_entry_id, respawn_time FROM persisted_respawns WHERE zone_id = %u AND spawn_type = %u", zone_id, type) ) if( !database_new.Select(&result, "SELECT spawn_location_entry_id, respawn_time FROM persisted_respawns WHERE zone_id = %u AND spawn_type = %u", zone_id, type) )
{ {
LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in GetInstanceRemovedSpawns() '%s': %i", database_new.GetErrorMsg(), database_new.GetError()); if(database_new.GetError()) {
LogWrite(ZONE__ERROR, 0, "Zone", "Error in GetPersistedSpawns() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
}
else {
}
return ret; return ret;
} }
else else
@ -6161,13 +6166,13 @@ map<int32,int32>* WorldDatabase::GetPersistedSpawns(int32 zone_id, int8 type)
*/ */
int32 respawntime = result.GetInt32Str("respawn_time"); int32 respawntime = result.GetInt32Str("respawn_time");
LogWrite(INSTANCE__DEBUG, 5, "Instance", "Found persisted spawn point: %u, respawn time: %u", spawn_location_entry_id, respawntime); LogWrite(ZONE__ERROR, 5, "Zone", "Found persisted spawn point: %u, respawn time: %u", spawn_location_entry_id, respawntime);
ret->insert(make_pair(spawn_location_entry_id, respawntime)); ret->insert(make_pair(spawn_location_entry_id, respawntime));
} }
} }
else else
LogWrite(INSTANCE__DEBUG, 0, "Instance", "No persisted spawns found for zone_id: %u, spawn_type: %u", zone_id, type); LogWrite(ZONE__ERROR, 0, "Zone", "No persisted spawns found for zone_id: %u, spawn_type: %u", zone_id, type);
} }

View File

@ -183,6 +183,8 @@ ZoneServer::ZoneServer(const char* name) {
groupraidFirstLevel = 0; groupraidFirstLevel = 0;
is_initialized = false; is_initialized = false;
isInstance = false;
duplicated_zone = false;
} }
typedef map <int32, bool> ChangedSpawnMapType; typedef map <int32, bool> ChangedSpawnMapType;
@ -2045,6 +2047,15 @@ void ZoneServer::CheckRespawns(){
} }
} }
void ZoneServer::SendRespawnTimerList(Client* client){
MutexMap<int32, int32>::iterator itr = respawn_timers.begin();
client->Message(CHANNEL_FACTION, "Respawn Timers:");
client->Message(CHANNEL_FACTION, "Location ID : Time Remaining");
while(itr.Next()){
client->Message(CHANNEL_FACTION, "%u: %i seconds.", itr->first, (itr->second - Timer::GetCurrentTime2())/1000);
}
}
void ZoneServer::CheckSpawnExpireTimers() { void ZoneServer::CheckSpawnExpireTimers() {
MutexMap<int32, int32>::iterator itr = spawn_expire_timers.begin(); MutexMap<int32, int32>::iterator itr = spawn_expire_timers.begin();
while (itr.Next()) { while (itr.Next()) {
@ -2516,12 +2527,18 @@ Spawn* ZoneServer::ProcessSpawnLocation(SpawnLocation* spawnlocation, map<int32,
continue; continue;
int32 spawnTime = 0; int32 spawnTime = 1;
/*if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_NPC) if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_NPC)
spawnTime = database.CheckSpawnRemoveInfo(instNPCs,spawnlocation->entities[i]->spawn_location_id); spawnTime = database.CheckSpawnRemoveInfo(instNPCs,spawnlocation->entities[i]->spawn_location_id);
else if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_OBJECT) else if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_OBJECT)
spawnTime = database.CheckSpawnRemoveInfo(instObjSpawns,spawnlocation->entities[i]->spawn_location_id); spawnTime = database.CheckSpawnRemoveInfo(instObjSpawns,spawnlocation->entities[i]->spawn_location_id);
else if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_WIDGET)
spawnTime = database.CheckSpawnRemoveInfo(instWidgetSpawns,spawnlocation->entities[i]->spawn_location_id);
else if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_SIGN)
spawnTime = database.CheckSpawnRemoveInfo(instSignSpawns,spawnlocation->entities[i]->spawn_location_id);
else if(spawnlocation->entities[i]->spawn_type == SPAWN_ENTRY_TYPE_GROUNDSPAWN)
spawnTime = database.CheckSpawnRemoveInfo(instGroundSpawns,spawnlocation->entities[i]->spawn_location_id);
if(spawnTime == 0) { // don't respawn if(spawnTime == 0) { // don't respawn
return nullptr; return nullptr;
@ -2529,7 +2546,7 @@ Spawn* ZoneServer::ProcessSpawnLocation(SpawnLocation* spawnlocation, map<int32,
else if(spawnTime > 1) { // if not 1, respawn after time else if(spawnTime > 1) { // if not 1, respawn after time
AddRespawn(spawnlocation->entities[i]->spawn_location_id, spawnTime); AddRespawn(spawnlocation->entities[i]->spawn_location_id, spawnTime);
return nullptr; return nullptr;
}*/ }
if (spawnlocation->conditional > 0) { if (spawnlocation->conditional > 0) {
if ((spawnlocation->conditional & SPAWN_CONDITIONAL_DAY) == SPAWN_CONDITIONAL_DAY && isDusk) if ((spawnlocation->conditional & SPAWN_CONDITIONAL_DAY) == SPAWN_CONDITIONAL_DAY && isDusk)
@ -8722,12 +8739,20 @@ void ZoneServer::SendFlightPathsPackets(Client* client) {
vector<FlightPathLocation*>::iterator itr2; vector<FlightPathLocation*>::iterator itr2;
int32 j = 0; int32 j = 0;
for (itr2 = m_flightPathRoutes[itr->first].begin(); itr2 != m_flightPathRoutes[itr->first].end(); itr2++, j++) { for (itr2 = m_flightPathRoutes[itr->first].begin(); itr2 != m_flightPathRoutes[itr->first].end(); itr2++, j++) {
packet->setSubArrayDataByName("x", (*itr2)->X, i, j); if(client->GetVersion() <= 561) {
packet->setSubArrayDataByName("y", (*itr2)->Y, i, j); std::string fieldNum = std::to_string(i) + "_" + std::to_string(j);
packet->setSubArrayDataByName("z", (*itr2)->Z, i, j); packet->setDataByName(("x" + fieldNum).c_str(), (*itr2)->X);
packet->setDataByName(("y" + fieldNum).c_str(), (*itr2)->Y);
packet->setDataByName(("z" + fieldNum).c_str(), (*itr2)->Z);
}
else {
packet->setSubArrayDataByName("x", (*itr2)->X, i, j);
packet->setSubArrayDataByName("y", (*itr2)->Y, i, j);
packet->setSubArrayDataByName("z", (*itr2)->Z, i, j);
}
} }
} }
packet->PrintPacket();
client->QueuePacket(packet->serialize()); client->QueuePacket(packet->serialize());
safe_delete(packet); safe_delete(packet);
} }

View File

@ -531,8 +531,10 @@ public:
inline bool IsCityZone() { return cityzone; } inline bool IsCityZone() { return cityzone; }
inline bool AlwaysLoaded() { return always_loaded; } inline bool AlwaysLoaded() { return always_loaded; }
inline bool DuplicatedZone() { return duplicated_zone; }
void SetCityZone(bool val) { cityzone = val; } void SetCityZone(bool val) { cityzone = val; }
void SetAlwaysLoaded(bool val) { always_loaded = val; } void SetAlwaysLoaded(bool val) { always_loaded = val; }
void SetDuplicatedZone(bool val) { duplicated_zone = val; }
int32 NumPlayers() { return pNumPlayers; } int32 NumPlayers() { return pNumPlayers; }
void SetMinimumStatus(sint16 minStatus) { minimumStatus = minStatus; } void SetMinimumStatus(sint16 minStatus) { minimumStatus = minStatus; }
sint16 GetMinimumStatus() { return minimumStatus; } sint16 GetMinimumStatus() { return minimumStatus; }
@ -732,6 +734,8 @@ public:
void AddRespawn(Spawn* spawn); void AddRespawn(Spawn* spawn);
void AddRespawn(int32 locationID, int32 respawnTime); void AddRespawn(int32 locationID, int32 respawnTime);
void SendRespawnTimerList(Client* client);
private: private:
#ifndef WIN32 #ifndef WIN32
pthread_t ZoneThread; pthread_t ZoneThread;
@ -934,6 +938,7 @@ private:
std::atomic<bool> is_initialized; std::atomic<bool> is_initialized;
bool cityzone; bool cityzone;
bool always_loaded; bool always_loaded;
bool duplicated_zone;
bool isInstance; bool isInstance;
std::atomic<int32> pNumPlayers; std::atomic<int32> pNumPlayers;