void Doors::HandleClick(Client* sender, uint8 trigger) { //door debugging info dump Log.Out(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str()); Log.Out(Logs::Detail, Logs::Doors, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param); Log.Out(Logs::Detail, Logs::Doors, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str()); EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; md->doorid = door_id; ///////////////////////////////////////////////////////////////// //used_pawn: Locked doors! Rogue friendly too =) //TODO: add check for other lockpick items ////////////////////////////////////////////////////////////////// //TODO: ADVENTURE DOOR if(IsLDoNDoor()) { if(sender) { if(RuleI(Adventure, ItemIDToEnablePorts) != 0) { if(!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) { if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) { sender->Message_StringID(13, DUNGEON_SEALED); safe_delete(outapp); return; } else { sender->KeyRingAdd(RuleI(Adventure, ItemIDToEnablePorts)); } } } if(!sender->GetPendingAdventureDoorClick()) { sender->PendingAdventureDoorClick(); ServerPacket *pack = new ServerPacket(ServerOP_AdventureClickDoor, sizeof(ServerPlayerClickedAdventureDoor_Struct)); ServerPlayerClickedAdventureDoor_Struct *ads = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer; strcpy(ads->player, sender->GetName()); ads->zone_id = zone->GetZoneID(); ads->id = GetDoorDBID(); worldserver.SendPacket(pack); safe_delete(pack); safe_delete(outapp); } return; } } uint32 keyneeded = GetKeyItem(); uint8 keepoffkeyring = GetNoKeyring(); uint32 haskey = 0; uint32 playerkey = 0; const ItemInst *lockpicks = sender->GetInv().GetItem(MainCursor); haskey = sender->GetInv().HasItem(keyneeded, 1); if (haskey != INVALID_INDEX) { playerkey = keyneeded; } if(GetTriggerType() == 255) { // this object isnt triggered if(trigger == 1) { // this door is only triggered by an object if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { safe_delete(outapp); return; } } // guild doors if(((keyneeded == 0) && (GetLockpick() == 0) && (guild_id == 0)) || (IsDoorOpen() && (opentype == 58)) || ((guild_id > 0) && (guild_id == sender->GuildID()))) { //door not locked if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { // guild doors if((guild_id > 0) && !sender->GetGM()) { std::string tmp; char tmpmsg[240]; // guild doors msgs if(guild_mgr.GetGuildNameByID(guild_id, tmp)) { sprintf(tmpmsg, "Only members of the <%s> guild may enter here", tmp.c_str()); } else { strcpy(tmpmsg, "Door is locked by an unknown guild"); } sender->Message(4, tmpmsg); safe_delete(outapp); return; } // a key is required or the door is locked but can be picked or both sender->Message(4, "This is locked..."); // debug spam - should probably go if(sender->GetGM()) // GM can always open locks - should probably be changed to require a key { sender->Message_StringID(4,DOORS_GM); if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else if(playerkey) { // they have something they are trying to open it with if(keyneeded && (keyneeded == playerkey)) { // key required and client is using the right key if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } sender->Message(4, "You got it open!"); if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } } else if(lockpicks != nullptr) { if(sender->GetSkill(SkillPickLock)) { if(lockpicks->GetItem()->ItemType == ItemTypeLockPick) { float modskill=sender->GetSkill(SkillPickLock); sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1); Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill); if(GetLockpick() <= modskill) { if(!IsDoorOpen()) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK); } else { sender->Message_StringID(4, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } } else { sender->Message_StringID(4, DOORS_NO_PICK); safe_delete(outapp); return; } } else { sender->Message_StringID(4, DOORS_CANT_PICK); safe_delete(outapp); return; } } else { // locked door and nothing to open it with // search for key on keyring if(sender->KeyRingCheck(keyneeded)) { playerkey = keyneeded; sender->Message(4, "You got it open!"); // more debug spam if(!IsDoorOpen() || (opentype == 58)) { md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR; } else { md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; } } else { sender->Message_StringID(4, DOORS_LOCKED); safe_delete(outapp); return; } } } entity_list.QueueClients(sender, outapp, false); if(!IsDoorOpen() || (opentype == 58)) { close_timer.Start(); SetOpenState(true); } else { close_timer.Disable(); SetOpenState(false); } //everything past this point assumes we opened the door //and met all the reqs for opening //everything to do with closed doors has already been taken care of //we return because we don't want people using teleports on an unlocked door (exploit!) if((md->action == CLOSE_DOOR && invert_state == 0) || (md->action == CLOSE_INVDOOR && invert_state == 1)) { safe_delete(outapp); return; } safe_delete(outapp); if((GetTriggerDoorID() != 0) && (GetTriggerType() == 1)) { Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); if(triggerdoor && !triggerdoor->triggered) { triggered=true; triggerdoor->HandleClick(sender, 1); } else { triggered=false; } } else if((GetTriggerDoorID() != 0) && (GetTriggerType() != 1)) { Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID()); if(triggerdoor && !triggerdoor->triggered) { triggered=true; triggerdoor->HandleClick(sender, 0); } else { triggered=false; } } if(((opentype == 57) || (opentype == 58)) && (strncmp(dest_zone, "NONE", strlen("NONE")) != 0)) { // Teleport door! if (( strncmp(dest_zone,zone_name,strlen(zone_name)) == 0) && (!keyneeded)) { if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM()))) { if(!keepoffkeyring) { sender->KeyRingAdd(playerkey); } if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } else { sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } } if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded)) { if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } else { sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w); } } } }
void SpawnConditionManager::ToggleEvent(uint32 event_id, bool enabled, bool strict, bool reset_base) { Log(Logs::Detail, Logs::Spawns, "Request to %s spawn event %d %sresetting trigger time", enabled?"enable":"disable", event_id, reset_base?"":"without "); //first look for the event in our local event list std::vector<SpawnEvent>::iterator cur,end; cur = spawn_events.begin(); end = spawn_events.end(); for(; cur != end; ++cur) { SpawnEvent &cevent = *cur; if(cevent.id == event_id) { //make sure were actually changing something if(cevent.enabled != enabled || reset_base || cevent.strict != strict) { cevent.enabled = enabled; cevent.strict = strict; if(reset_base) { Log(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone. State set. Trigger time reset (period %d).", event_id, cevent.period); //start with the time now zone->zone_time.GetCurrentEQTimeOfDay(&cevent.next); //advance the next time by our period EQTime::AddMinutes(cevent.period, &cevent.next); } else { Log(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone. State changed.", event_id); } //save the event in the DB UpdateDBEvent(cevent); //sync up our nearest event FindNearestEvent(); } else { Log(Logs::Detail, Logs::Spawns, "Spawn event %d located in this zone but no change was needed.", event_id); } //even if we dont change anything, we still found it return; } } //if we get here, the condition must be in another zone. //first figure out what zone it applies to. //update the DB and send and send an update packet to //the zone if its up //we need to load the event from the DB and then update //the values in the DB, because we do not know if the zone //is up or not. The message to the zone will just tell it to //update its in-memory event list SpawnEvent e; std::string zone_short_name; if(!LoadDBEvent(event_id, e, zone_short_name)) { Log(Logs::Detail, Logs::Spawns, "Unable to find spawn event %d in the database.", event_id); //unable to find the event in the database... return; } if(e.enabled == enabled && !reset_base) { Log(Logs::Detail, Logs::Spawns, "Spawn event %d is not located in this zone but no change was needed.", event_id); return; //no changes. } e.enabled = enabled; if(reset_base) { Log(Logs::Detail, Logs::Spawns, "Spawn event %d is in zone %s. State set. Trigger time reset (period %d). Notifying world.", event_id, zone_short_name.c_str(), e.period); //start with the time now zone->zone_time.GetCurrentEQTimeOfDay(&e.next); //advance the next time by our period EQTime::AddMinutes(e.period, &e.next); } else { Log(Logs::Detail, Logs::Spawns, "Spawn event %d is in zone %s. State changed. Notifying world.", event_id, zone_short_name.c_str(), e.period); } //save the event in the DB UpdateDBEvent(e); //now notify the zone auto pack = new ServerPacket(ServerOP_SpawnEvent, sizeof(ServerSpawnEvent_Struct)); ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*)pack->pBuffer; sse->zoneID = database.GetZoneID(zone_short_name.c_str()); sse->event_id = event_id; worldserver.SendPacket(pack); safe_delete(pack); }
bool Corpse::Process() { if (player_corpse_depop) return false; if (corpse_delay_timer.Check()) { for (int i = 0; i < MAX_LOOTERS; i++) allowed_looters[i] = 0; corpse_delay_timer.Disable(); return true; } if (corpse_graveyard_timer.Check()) { if (zone->HasGraveyard()) { Save(); player_corpse_depop = true; database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint()); corpse_graveyard_timer.Disable(); auto pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; spc->player_corpse_id = corpse_db_id; spc->zone_id = zone->graveyard_zoneid(); worldserver.SendPacket(pack); safe_delete(pack); Log.Out(Logs::General, Logs::None, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid())); corpse_db_id = 0; } corpse_graveyard_timer.Disable(); return false; } /* if(corpse_res_timer.Check()) { can_rez = false; corpse_res_timer.Disable(); } */ /* This is when a corpse hits decay timer and does checks*/ if (corpse_decay_timer.Check()) { /* NPC */ if (IsNPCCorpse()){ corpse_decay_timer.Disable(); return false; } /* Client */ if (!RuleB(Zone, EnableShadowrest)){ Delete(); } else { if (database.BuryCharacterCorpse(corpse_db_id)) { Save(); player_corpse_depop = true; corpse_db_id = 0; Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has buried.", this->GetName()); } else { Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName()); return true; } } corpse_decay_timer.Disable(); return false; } return true; }
void SpawnConditionManager::SetCondition(const char *zone_short, uint32 instance_id, uint16 condition_id, int16 new_value, bool world_update) { if(world_update) { //this is an update coming from another zone, they //have allready updated the DB, just need to update our //memory, and check for condition changes std::map<uint16, SpawnCondition>::iterator condi; condi = spawn_conditions.find(condition_id); if(condi == spawn_conditions.end()) { Log(Logs::Detail, Logs::Spawns, "Condition update received from world for %d, but we do not have that conditon.", condition_id); return; //unable to find the spawn condition } SpawnCondition &cond = condi->second; if(cond.value == new_value) { Log(Logs::Detail, Logs::Spawns, "Condition update received from world for %d with value %d, which is what we already have.", condition_id, new_value); return; } int16 old_value = cond.value; //set our local value cond.value = new_value; Log(Logs::Detail, Logs::Spawns, "Condition update received from world for %d with value %d", condition_id, new_value); //now we have to test each spawn point to see if it changed. zone->SpawnConditionChanged(cond, old_value); } else if(!strcasecmp(zone_short, zone->GetShortName()) && instance_id == zone->GetInstanceID()) { //this is a local spawn condition, we need to update the DB, //our memory, then notify spawn points of the change. std::map<uint16, SpawnCondition>::iterator condi; condi = spawn_conditions.find(condition_id); if(condi == spawn_conditions.end()) { Log(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d, but we do not have that conditon.", condition_id); return; //unable to find the spawn condition } SpawnCondition &cond = condi->second; if(cond.value == new_value) { Log(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d with value %d, which is what we already have.", condition_id, new_value); return; } int16 old_value = cond.value; //set our local value cond.value = new_value; //save it in the DB too UpdateDBCondition(zone_short, instance_id, condition_id, new_value); Log(Logs::Detail, Logs::Spawns, "Local Condition update requested for %d with value %d", condition_id, new_value); //now we have to test each spawn point to see if it changed. zone->SpawnConditionChanged(cond, old_value); } else { //this is a remote spawn condition, update the DB and send //an update packet to the zone if its up Log(Logs::Detail, Logs::Spawns, "Remote spawn condition %d set to %d. Updating DB and notifying world.", condition_id, new_value); UpdateDBCondition(zone_short, instance_id, condition_id, new_value); auto pack = new ServerPacket(ServerOP_SpawnCondition, sizeof(ServerSpawnCondition_Struct)); ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*)pack->pBuffer; ssc->zoneID = database.GetZoneID(zone_short); ssc->instanceID = instance_id; ssc->condition_id = condition_id; ssc->value = new_value; worldserver.SendPacket(pack); safe_delete(pack); } }
bool Group::DelMember(Mob* oldmember,bool ignoresender) { if (oldmember == nullptr) { return false; } for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) { if (members[i] == oldmember) { members[i] = nullptr; membername[i][0] = '\0'; memset(membername[i],0,64); MemberRoles[i] = 0; Log.Out(Logs::Detail, Logs::Group, "DelMember: Removed Member: %s", oldmember->GetCleanName()); break; } } if(GroupCount() < 2) { DisbandGroup(); return true; } // If the leader has quit and we have 2 or more players left in group, we want to first check the zone the old leader was in for a new leader. // If a suitable replacement cannot be found, we need to go out of zone. If checkleader remains true after this method completes, another // loop will be run in DelMemberOOZ. bool checkleader = true; if (strcmp(GetOldLeaderName(),oldmember->GetCleanName()) == 0 && GroupCount() >= 2) { for(uint32 nl = 0; nl < MAX_GROUP_MEMBERS; nl++) { if(members[nl]) { if (members[nl]->IsClient()) { ChangeLeader(members[nl]); checkleader = false; break; } } } } ServerPacket* pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct)); ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer; gl->gid = GetID(); gl->zoneid = zone->GetZoneID(); gl->instance_id = zone->GetInstanceID(); strcpy(gl->member_name, oldmember->GetName()); gl->checkleader = checkleader; worldserver.SendPacket(pack); safe_delete(pack); EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer; gu->action = groupActLeave; strcpy(gu->membername, oldmember->GetCleanName()); strcpy(gu->yourname, oldmember->GetCleanName()); for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) { if (members[i] == nullptr) { //if (DEBUG>=5) Log.Out(Logs::Detail, Logs::Group, "Group::DelMember() null member at slot %i", i); continue; } if (members[i] != oldmember) { strcpy(gu->yourname, members[i]->GetCleanName()); if(members[i]->IsClient()) members[i]->CastToClient()->QueuePacket(outapp); } } if (!ignoresender) { strcpy(gu->yourname,oldmember->GetCleanName()); strcpy(gu->membername,oldmember->GetCleanName()); gu->action = groupActLeave; if(oldmember->IsClient()) oldmember->CastToClient()->QueuePacket(outapp); } if(oldmember->IsClient()) { database.SetGroupID(oldmember->GetCleanName(), 0, oldmember->CastToClient()->CharacterID()); } oldmember->SetGrouped(false); disbandcheck = true; safe_delete(outapp); return true; }
void Client::GuildCommand(Seperator* sep) { zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (strcasecmp(sep->arg[1], "help") == 0) { this->GuildPCCommandHelp(); this->GuildGMCommandHelp(); } else if (strcasecmp(sep->arg[1], "status") == 0 || strcasecmp(sep->arg[1], "stat") == 0) { Client* client = 0; if (sep->arg[2][0] != 0) { client = entity_list.GetClientByName(sep->argplus[2]); } else if (target != 0 && target->IsClient()) { client = target->CastToClient(); } if (client == 0) { this->Message(BLACK, "You must target someone or specify a character name"); } else if ((client->Admin() >= 100 && admin < 100) && client->GuildDBID() != guilddbid) // no peeping for GMs, make sure tell message stays the same { this->Message(BLACK, "You must target someone or specify a character name."); } else { if (client->GuildDBID() == 0) { this->Message(BLACK, "%s is not in a guild.", client->GetName()); } else if (guilds[client->GuildEQID()].leader == client->AccountID()) { this->Message(BLACK, "%s is the leader of <%s> rank: %s", client->GetName(), guilds[client->GuildEQID()].name, guilds[client->GuildEQID()].rank[client->GuildRank()].rankname); } else { this->Message(BLACK, "%s is a member of <%s> rank: %s", client->GetName(), guilds[client->GuildEQID()].name, guilds[client->GuildEQID()].rank[client->GuildRank()].rankname); } } } else if (strcasecmp(sep->arg[1], "info") == 0) { if (sep->arg[2][0] == 0 && guilddbid == 0) { if (admin >= 100) { this->Message(BLACK, "Usage: #guildinfo guilddbid"); } else { this->Message(BLACK, "You're not in a guild"); } } else { int32 tmp; if (sep->arg[2][0] == 0) { tmp = Database::Instance()->GetGuildEQID(guilddbid); } else { tmp = Database::Instance()->GetGuildEQID(atoi(sep->arg[2])); } if (tmp < 0 || tmp >= 512) { this->Message(BLACK, "Guild not found."); } else { this->Message(BLACK, "Guild info DB# %i, %s", guilds[tmp].databaseID, guilds[tmp].name); if (this->admin >= 100 || guildeqid == tmp) { if (this->account_id == guilds[tmp].leader || guildrank == 0 || admin >= 100) { char leadername[32]; Database::Instance()->GetAccountName(guilds[tmp].leader, leadername); this->Message(BLACK, "Guild Leader: %s", leadername); } for (int i = 0; i <= GUILD_MAX_RANK; i++) { this->Message(BLACK, "Rank %i: %s", i, guilds[tmp].rank[i].rankname); this->Message(BLACK, " HearGU: %i SpeakGU: %i Invite: %i Remove: %i Promote: %i Demote: %i MOTD: %i War/Peace: %i", guilds[tmp].rank[i].heargu, guilds[tmp].rank[i].speakgu, guilds[tmp].rank[i].invite, guilds[tmp].rank[i].remove, guilds[tmp].rank[i].promote, guilds[tmp].rank[i].demote, guilds[tmp].rank[i].motd, guilds[tmp].rank[i].warpeace); } } } } } else if (strcasecmp(sep->arg[1], "leader") == 0) { if (guilddbid == 0) { this->Message(BLACK, "You arent in a guild!"); } else if (guilds[guildeqid].leader != account_id) { this->Message(BLACK, "You aren't the guild leader."); } else { char* tmptar = 0; if (sep->arg[2][0] != 0) { tmptar = sep->argplus[2]; } else if (tmptar == 0 && target != 0 && target->IsClient()) { tmptar = target->CastToClient()->GetName(); } if (tmptar == 0) { Message(BLACK, "You must target someone or specify a character name."); } else { // Dark-Prince - 10/05/2008 - Code Consolidation //zgm.InviteToGuild( //this->SendGuildInvitePacket(tmptar); } } } else if (strcasecmp(sep->arg[1], "invite") == 0) { int32 GuildDBID = atoi(sep->arg[2]); Client* Invitee = entity_list.GetClientByName(sep->arg[3]); GUILDRANK Rank = (GUILDRANK)atoi(sep->arg[4]); int32 GuidlEQID = Database::Instance()->GetGuildEQID(GuildDBID); zgm.InviteToGuild(GuildDBID, GuidlEQID, this, Invitee, Rank); } else if (strcasecmp(sep->arg[1], "remove") == 0) { Client* Removee = entity_list.GetClientByName(sep->arg[2]); if(Removee != 0) { zgm.RemovePCFromGuild(this, Removee); } } else if (strcasecmp(sep->arg[1], "promote") == 0) { if (guilddbid == 0) { Message(BLACK, "You arent in a guild!"); } else if (!(strlen(sep->arg[2]) == 1 && sep->arg[2][0] >= '0' && sep->arg[2][0] <= '9')) { Message(BLACK, "Usage: #guild promote rank [charname]"); } else if (atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > GUILD_MAX_RANK) { Message(BLACK, "Error: invalid rank #."); } else { char* tmptar = 0; if (sep->arg[3][0] != 0) { tmptar = sep->argplus[3]; } else if (tmptar == 0 && target != 0 && target->IsClient()) { tmptar = target->CastToClient()->GetName(); } if (tmptar == 0) { Message(BLACK, "You must target someone or specify a character name."); } else { zgm.SendGuildPromotePacket(tmptar, this->GetName()); } } } else if (strcasecmp(sep->arg[1], "demote") == 0) { if (guilddbid == 0) { Message(BLACK, "You arent in a guild!"); } else if (!(strlen(sep->arg[2]) == 1 && sep->arg[2][0] >= '0' && sep->arg[2][0] <= '9')) { Message(BLACK, "Usage: #guild demote rank [charname]"); } else if (atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > GUILD_MAX_RANK) { Message(BLACK, "Error: invalid rank #."); } else { char* tmptar = 0; if (sep->arg[3][0] != 0) { tmptar = sep->argplus[3]; } else if (tmptar == 0 && target != 0 && target->IsClient()) { tmptar = target->CastToClient()->GetName(); } if (tmptar == 0) { Message(BLACK, "You must target someone or specify a character name."); } else { zgm.SendGuildDemotePacket(tmptar); } } } else if (strcasecmp(sep->arg[1], "motd") == 0) { if (guilddbid == 0) { Message(BLACK, "You arent in a guild!"); } else if (!guilds[guildeqid].rank[guildrank].motd) { Message(BLACK, "You dont have permission to change the motd."); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { char tmp[255]; if (strcasecmp(sep->argplus[2], "none") == 0) { strcpy(tmp, ""); } else { snprintf(tmp, sizeof(tmp), "%s - %s", this->GetName(), sep->argplus[2]); } if (Database::Instance()->SetGuildMOTD(guilddbid, tmp)) { // Dark-Prince - 10/05/2008 - Code Consolidation /* ServerPacket* pack = new ServerPacket; pack->opcode = ServerOP_RefreshGuild; pack->size = 5; pack->pBuffer = new uchar[pack->size]; memcpy(pack->pBuffer, &guildeqid, 4); worldserver.SendPacket(pack); safe_delete(pack);//delete pack; */ } else { this->Message(BLACK, "Motd update failed."); } } } else if (strcasecmp(sep->arg[1], "edit") == 0) { if (guilddbid == 0) { Message(BLACK, "You arent in a guild!"); } else if (!sep->IsNumber(2)) { Message(BLACK, "Error: invalid rank #."); } else if (atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > GUILD_MAX_RANK) { Message(BLACK, "Error: invalid rank #."); } else if (!guildrank == 0) { Message(BLACK, "You must be rank %s to use edit.", guilds[guildeqid].rank[0].rankname); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { if (!GuildEditCommand(guilddbid, guildeqid, atoi(sep->arg[2]), sep->arg[3], sep->argplus[4])) { Message(BLACK, " #guild edit rank title newtitle"); Message(BLACK, " #guild edit rank permission 0/1"); } else { zgm.SendGuildRefreshPacket(guildeqid); } } } // Start of GM Guild Commands else if (strcasecmp(sep->arg[1], "gmedit") == 0 && admin >= 100) { if (!sep->IsNumber(2)) { Message(BLACK, "Error: invalid guilddbid."); } else if (!sep->IsNumber(3)) { Message(BLACK, "Error: invalid rank #."); } else if (atoi(sep->arg[3]) < 0 || atoi(sep->arg[3]) > GUILD_MAX_RANK) { Message(BLACK, "Error: invalid rank #."); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { int32 eqid = Database::Instance()->GetGuildEQID(atoi(sep->arg[2])); if (eqid == 0xFFFFFFFF) { Message(BLACK, "Error: Guild not found"); } else if (!GuildEditCommand(atoi(sep->arg[2]), eqid, atoi(sep->arg[3]), sep->arg[4], sep->argplus[5])) { Message(BLACK, " #guild gmedit guilddbid rank title newtitle"); Message(BLACK, " #guild gmedit guilddbid rank permission 0/1"); } else { zgm.SendGuildRefreshPacket(eqid); } } } else if (strcasecmp(sep->arg[1], "set") == 0 && admin >= 100) { if (!sep->IsNumber(3)) { Message(BLACK, "Usage: #guild set charname guildgbid (0 = clear guildtag)"); } else { /* -- Work in progress GUILDRANK rank = GuildMember; Client* c = entity_list.GetClientByName(sep->arg[2]); if(c == 0) { Message(BLACK, "Player not found!"); return; } int GuidDBID = atoi(sep->arg[3]); if(sep->IsNumber(4)) { rank = (GUILDRANK)atoi(sep->arg[4]); } zgm.LoadGuilds(); int32 GuidEQID = Database::Instance()->GetGuildEQID(GuidDBID); zgm.InviteToGuild(GuidDBID, GuidEQID, this, c, rank); */ ServerPacket* pack = new ServerPacket(ServerOP_GuildGMSet, sizeof(ServerGuildCommand_Struct)); pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; sgc->guilddbid = atoi(sep->arg[3]); sgc->admin = admin; strcpy(sgc->from, name); strcpy(sgc->target, sep->arg[2]); worldserver.SendPacket(pack); safe_delete(pack);//delete pack; } } else if (strcasecmp(sep->arg[1], "setrank") == 0 && admin >= 100) { if (!sep->IsNumber(3)) { Message(BLACK, "Usage: #guild setrank charname rank"); } else if (atoi(sep->arg[3]) < 0 || atoi(sep->arg[3]) > GUILD_MAX_RANK) { Message(BLACK, "Error: invalid rank #."); } else { ServerPacket* pack = new ServerPacket(ServerOP_GuildGMSetRank, sizeof(ServerGuildCommand_Struct)); pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; sgc->newrank = (GUILDRANK)atoi(sep->arg[3]); sgc->admin = admin; strcpy(sgc->from, name); strcpy(sgc->target, sep->arg[2]); worldserver.SendPacket(pack); target->CastToClient()->SetGuild(target->CastToClient()->guilddbid, sgc->newrank); safe_delete(pack);//delete pack; } } /* New Guild Creation -> Challenge/Response method */ else if (strcasecmp(sep->arg[1], "dpcreate") == 0 && admin >= 100) { if (sep->arg[3][0] == 0) { Message(BLACK, "Usage: #guild create {guildleader charname or AccountID} guild name"); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { zgm.CreateGuildRequest(this, sep->arg[2], sep->argplus[3]); } } /* END New Guild Creation -> Challenge/Response method */ else if (strcasecmp(sep->arg[1], "create") == 0 && admin >= 100) { if (sep->arg[3][0] == 0) { Message(BLACK, "Usage: #guild create {guildleader charname or AccountID} guild name"); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { Client* Leader = entity_list.GetClientByName(sep->arg[2]); int32 guilddbid = 0; if(Leader != 0) { zgm.CreateGuild(this, Leader, sep->argplus[3], guilddbid); } } } else if (strcasecmp(sep->arg[1], "delete") == 0 && admin >= 100) { if (!sep->IsNumber(2)) { Message(BLACK, "Usage: #guild delete guildDBID"); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { int32 tmpeq = Database::Instance()->GetGuildEQID(atoi(sep->arg[2])); char tmpname[32]; if (tmpeq != 0xFFFFFFFF) { strcpy(tmpname, guilds[tmpeq].name); } if (!Database::Instance()->DeleteGuild(atoi(sep->arg[2]))) { Message(BLACK, "Guild delete failed."); } else { if (tmpeq != 0xFFFFFFFF) { zgm.LoadGuilds(); ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, 5); pack->pBuffer = new uchar[pack->size]; memcpy(pack->pBuffer, &tmpeq, 4); pack->pBuffer[4] = 1; worldserver.SendPacket(pack); safe_delete(pack);//delete pack; Message(BLACK, "Guild deleted: DB# %i, EQ# %i: %s", atoi(sep->arg[2]), tmpeq, tmpname); } else { Message(BLACK, "Guild deleted: DB# %i", atoi(sep->arg[2])); } } } } else if (strcasecmp(sep->arg[1], "rename") == 0 && admin >= 100) { if ((!sep->IsNumber(2)) || sep->arg[3][0] == 0) { Message(BLACK, "Usage: #guild rename guildDBID newname"); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { int32 tmpeq = Database::Instance()->GetGuildEQID(atoi(sep->arg[2])); char tmpname[32]; if (tmpeq != 0xFFFFFFFF) { strcpy(tmpname, guilds[tmpeq].name); } if (!Database::Instance()->RenameGuild(atoi(sep->arg[2]), sep->argplus[3])) { Message(BLACK, "Guild rename failed."); } else { if (tmpeq != 0xFFFFFFFF) { ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, 5); pack->pBuffer = new uchar[pack->size]; memcpy(pack->pBuffer, &tmpeq, 4); pack->pBuffer[4] = 1; worldserver.SendPacket(pack); safe_delete(pack);//delete pack; Message(BLACK, "Guild renamed: DB# %i, EQ# %i, OldName: %s, NewName: %s", atoi(sep->arg[2]), tmpeq, tmpname, sep->argplus[3]); } else { Message(BLACK, "Guild renamed: DB# %i, NewName: %s", atoi(sep->arg[2]), sep->argplus[3]); } } } } else if (strcasecmp(sep->arg[1], "setleader") == 0 && admin >= 100) { if (sep->arg[3][0] == 0 || !sep->IsNumber(2)) { Message(BLACK, "Usage: #guild setleader guilddbid {guildleader charname or AccountID}"); } else if (!worldserver.Connected()) { Message(BLACK, "Error: World server dirconnected"); } else { int32 leader = 0; if (sep->IsNumber(3)) { leader = atoi(sep->arg[3]); } else { leader = Database::Instance()->GetAccountIDByChar(sep->argplus[3]); } int32 tmpdb = Database::Instance()->GetGuildDBIDbyLeader(leader); if (leader == 0) { Message(BLACK, "New leader not found."); } else if (tmpdb != 0) { int32 tmpeq = Database::Instance()->GetGuildEQID(tmpdb); if (tmpeq >= 512) { Message(BLACK, "Error: %s already is the leader of DB# %i.", sep->argplus[3], tmpdb); } else { Message(BLACK, "Error: %s already is the leader of DB# %i <%s>.", sep->argplus[3], tmpdb, guilds[tmpeq].name); } } else { int32 tmpeq = Database::Instance()->GetGuildEQID(atoi(sep->arg[2])); if (tmpeq == 0xFFFFFFFF) { Message(BLACK, "Guild not found."); } else if (!Database::Instance()->SetGuildLeader(atoi(sep->arg[2]), leader)) { Message(BLACK, "Guild leader change failed."); } else { zgm.SendGuildRefreshPacket(tmpeq); Message(BLACK, "Guild leader changed: DB# %s, Leader: %s, Name: <%s>", sep->arg[2], sep->argplus[3], guilds[tmpeq].name); } } } } else if (strcasecmp(sep->arg[1], "list") == 0 && admin >= 100) { int x = 0; Message(BLACK, "Listing guilds on the server:"); char leadername[32]; int magicnumber = 512; zgm.LoadGuilds(); guilds = zgm.GetGuildList(); for (int i = 0; i < magicnumber; i++) { if (guilds[i].databaseID != 0) { leadername[0] = 0; Database::Instance()->GetAccountName(guilds[i].leader, leadername); if (leadername[0] == 0) { Message(BLACK, " DB# %i EQ# %i <%s>", guilds[i].databaseID, i, guilds[i].name); } else { Message(BLACK, " DB# %i EQ# %i <%s> Leader: %s", guilds[i].databaseID, i, guilds[i].name, leadername); } x++; } } Message(BLACK, "%i guilds listed.", x); } else if (strcasecmp(sep->arg[1], "reload") == 0 && admin >= 100) { Message(BLACK, "Reloading Guilds"); int32 eqdbid = atoi(sep->arg[2]); zgm.LoadGuilds(); zgm.SendGuildRefreshPacket(eqdbid); } else { Message(BLACK, "Unknown guild command, try #guild help"); } }
void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instance_id, float dest_x, float dest_y, float dest_z, float dest_h, int8 ignore_r) { //this is called once the client is fully allowed to zone here //it takes care of all the activities which occur when a client zones out SendLogoutPackets(); //dont clear aggro until the zone is successful entity_list.RemoveFromHateLists(this); if(this->GetPet()) entity_list.RemoveFromHateLists(this->GetPet()); LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z); //set the player's coordinates in the new zone so they have them //when they zone into it x_pos = dest_x; //these coordinates will now be saved when ~client is called y_pos = dest_y; z_pos = dest_z; heading = dest_h; // Cripp: fix for zone heading m_pp.heading = dest_h; m_pp.zone_id = zone_id; m_pp.zoneInstance = instance_id; //Force a save so its waiting for them when they zone Save(2); if (zone_id == zone->GetZoneID() && instance_id == zone->GetInstanceID()) { // No need to ask worldserver if we're zoning to ourselves (most // likely to a bind point), also fixes a bug since the default response was failure EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZoneChange,sizeof(ZoneChange_Struct)); ZoneChange_Struct* zc2 = (ZoneChange_Struct*) outapp->pBuffer; strcpy(zc2->char_name, GetName()); zc2->zoneID = zone_id; zc2->instanceID = instance_id; zc2->success = 1; outapp->priority = 6; FastQueuePacket(&outapp); zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { // vesuvias - zoneing to another zone so we need to the let the world server //handle things with the client for a while ServerPacket* pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct)); ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; ztz->response = 0; ztz->current_zone_id = zone->GetZoneID(); ztz->current_instance_id = zone->GetInstanceID(); ztz->requested_zone_id = zone_id; ztz->requested_instance_id = instance_id; ztz->admin = admin; ztz->ignorerestrictions = ignore_r; strcpy(ztz->name, GetName()); ztz->guild_id = GuildID(); worldserver.SendPacket(pack); safe_delete(pack); } //reset to unsolicited. zone_mode = ZoneUnsolicited; zonesummon_x = 0; zonesummon_y = 0; zonesummon_z = 0; zonesummon_id = 0; zonesummon_ignorerestrictions = 0; }
void WorldServer::Process() { if(this == 0) { return; } if(!Connected()) { return; } SOCKADDR_IN to; memset((char *) &to, 0, sizeof(to)); to.sin_family = AF_INET; to.sin_port = port; to.sin_addr.s_addr = ip; /************ Get all packets from packet manager out queue and process them ************/ ServerPacket *pack = 0; while(pack = ServerRecvQueuePop()) { switch(pack->opcode) { case 0: { break; } case ServerOP_KeepAlive: { // ignore this break; } case ServerOP_ChannelMessage: { if (!ZoneLoaded) break; ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; if (scm->deliverto[0] == 0) { entity_list.ChannelMessageFromWorld(scm->from, scm->to, scm->chan_num, scm->guilddbid, scm->language, scm->message); } else { Client* client; client = entity_list.GetClientByName(scm->deliverto); if (client != 0) { if (client->Connected()) { client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->message); if (!scm->noreply) { // if it's a tell, echo back so it shows up scm->noreply = true; scm->chan_num = 14; memset(scm->deliverto, 0, sizeof(scm->deliverto)); strcpy(scm->deliverto, scm->from); SendPacket(pack); } } } } break; } case ServerOP_EmoteMessage: { if (!ZoneLoaded) { break; } ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; if (sem->to[0] != 0) { if (strcasecmp(sem->to, zone->GetShortName()) == 0) { entity_list.Message(sem->guilddbid, (MessageFormat)sem->type, sem->message); } else { Client* client = entity_list.GetClientByName(sem->to); if (client != 0) { client->Message((MessageFormat)sem->type, sem->message); } } } else { entity_list.Message(sem->guilddbid, (MessageFormat)sem->type, sem->message); } break; } /* case ServerOP_GroupRefresh: //Kibanu - 4/22/2009 { cout << "WorldServer_Process: In Group Refresh" << endl; if (!ZoneLoaded) { break; } ServerGroupRefresh_Struct* gr = (ServerGroupRefresh_Struct*) pack->pBuffer; if (gr->member[0] != 0) { cout << "WorldServer_Process: Refreshing group for " << gr->member << endl; Client* client = entity_list.GetClientByName(gr->member); if (client != 0) { client->RefreshGroup(gr->gid, gr->action); } } break; }*/ case ServerOP_ShutdownAll: { entity_list.Save(); CatchSignal(2); break; } case ServerOP_ZoneShutdown: { // Annouce the change to the world if (!ZoneLoaded) { SetZone(""); } else { worldserver.SendEmoteMessage(0, 0, 15, "Zone shutdown: %s", zone->GetLongName()); ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer; cout << "Zone shutdown by " << zst->adminname << endl; Zone::Shutdown(); } break; } case ServerOP_ZoneBootup: { ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer; if (ZoneLoaded) { SetZone(zone->GetShortName()); if (strcasecmp(Database::Instance()->GetZoneName(zst->zoneid), zone->GetShortName()) == 0) { // This packet also doubles as "incomming client" notification, lets not shut down before they get here zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { worldserver.SendEmoteMessage(zst->adminname, 0, 0, "Zone bootup failed: Already running '%s'", zone->GetShortName()); } break; } if (zst->adminname[0] != 0) { cout << "Zone bootup by " << zst->adminname << endl; } if (!(Zone::Bootup(Database::Instance()->GetZoneName(zst->zoneid)))) { worldserver.SendChannelMessage(0, 0, 10, 0, 0, "%s:%i Zone::Bootup failed: %s", net.GetZoneAddress(), net.GetZonePort(), Database::Instance()->GetZoneName(zst->zoneid)); } break; } case ServerOP_ZonePlayer: { ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(szp->name); if (client != 0) { if (strcasecmp(szp->adminname, szp->name) == 0) { client->Message(BLACK, "Zoning to: %s", szp->zone); } else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) { break; } else { worldserver.SendEmoteMessage(szp->adminname, 0, 0, "Summoning %s to %s %1.1f, %1.1f, %1.1f", szp->name, szp->zone, szp->x_pos, szp->y_pos, szp->z_pos); } client->SetIsZoning(true); client->SetUsingSoftCodedZoneLine(true); client->SetZoningHeading(client->GetHeading()); client->SetZoningX(szp->x_pos); client->SetZoningY(szp->y_pos); client->SetZoningZ(szp->z_pos); client->ZonePC(szp->zone, szp->x_pos, szp->y_pos, szp->z_pos); } break; } // Cofruben: used to send a packet directly to a client. /* case ServerOP_SendPacket: { ServerSendPacket_Struct* sss = (ServerSendPacket_Struct*)pack->pBuffer; int32 PacketSize = pack->size - sizeof(sss->charname) - sizeof(sss->opcode); Client* PacketTo = entity_list.GetClientByName(sss->charname); if(!PacketTo) { break; } APPLAYER* outapp = new APPLAYER(sss->opcode, PacketSize); memcpy(outapp->pBuffer, sss->packet, PacketSize); PacketTo->QueuePacket(outapp); safe_delete(outapp);//delete outapp; break; }*/ case ServerOP_KickPlayer: { ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(skp->name); if (client != 0) { if (skp->adminrank >= client->Admin()) { client->Kick(); if (ZoneLoaded) { worldserver.SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted in zone %s.", skp->name, zone->GetShortName()); } else { worldserver.SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted.", skp->name); } } else if (client->GetAnon() != 1) { worldserver.SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: Your avatar level is not high enough to kick %s", skp->name); } } break; } case ServerOP_KillPlayer: { ServerKillPlayer_Struct* skp = (ServerKillPlayer_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(skp->target); if (client != 0) { if (skp->admin >= client->Admin()) { client->Kill(); if (ZoneLoaded) { worldserver.SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed in zone %s.", skp->target, zone->GetShortName()); } else { worldserver.SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed.", skp->target); } } else if (client->GetAnon() != 1) { worldserver.SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: Your avatar level is not high enough to kill %s", skp->target); } } break; } case ServerOP_RefreshGuild: { if (pack->size == 5) { int32 guildeqid = 0; memcpy(&guildeqid, pack->pBuffer, 4); zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (pack->pBuffer[4] == 1) { APPLAYER* outapp = new APPLAYER(OP_GuildUpdate, 64); memset(outapp->pBuffer, 0, outapp->size); GuildUpdate_Struct* gu = (GuildUpdate_Struct*) outapp->pBuffer; gu->guildID = guildeqid; gu->entry.guildID = guildeqid; if (guilds[guildeqid].databaseID == 0) { gu->entry.exists = 0; // = 0x01 if exists, 0x00 on empty } else { strcpy(gu->entry.name, guilds[guildeqid].name); gu->entry.exists = 1; // = 0x01 if exists, 0x00 on empty } gu->entry.unknown1[0] = 0xFF; gu->entry.unknown1[1] = 0xFF; gu->entry.unknown1[2] = 0xFF; gu->entry.unknown1[3] = 0xFF; gu->entry.unknown3[0] = 0xFF; gu->entry.unknown3[1] = 0xFF; gu->entry.unknown3[2] = 0xFF; gu->entry.unknown3[3] = 0xFF; entity_list.QueueClients(0, outapp, false); safe_delete(outapp);//delete outapp; } } else cout << "Wrong size: ServerOP_RefreshGuild. size=" << pack->size << endl; break; } case ServerOP_GuildLeader: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); if (client == 0) { // do nothing } else if (client->GuildDBID() != sgc->guilddbid) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is not in your guild.", client->GetName()); } else if ((client->GuildRank() != 0) || (client->GuildRank() != 1)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is not rank 0.", client->GetName()); } else { if (Database::Instance()->SetGuildLeader(sgc->guilddbid, client->AccountID())) { worldserver.SendEmoteMessage(0, sgc->guilddbid, MESSAGETYPE_Guild, "%s is now the leader of your guild.", client->GetName()); ServerPacket* pack2 = new ServerPacket(ServerOP_RefreshGuild, 4); pack2->pBuffer = new uchar[pack->size]; memcpy(pack2->pBuffer, &sgc->guildeqid, 4); worldserver.SendPacket(pack2); safe_delete(pack2);//delete pack2; } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Guild leadership transfer failed."); } } break; } case ServerOP_GuildInvite: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (client == 0) { // do nothing } else if (!guilds[sgc->guildeqid].rank[sgc->fromrank].invite) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You dont have permission to invite."); } else if (client->GuildDBID() != 0) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is already in another guild.", client->GetName()); } else if (client->PendingGuildInvite != 0 && !(client->PendingGuildInvite == sgc->guilddbid)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s has another pending guild invite.", client->GetName()); } else { client->PendingGuildInvite = sgc->guilddbid; APPLAYER* outapp = new APPLAYER(OP_GuildInvite, sizeof(GuildCommand_Struct)); memset(outapp->pBuffer, 0, outapp->size); GuildCommand_Struct* gc = (GuildCommand_Struct*) outapp->pBuffer; gc->guildeqid = sgc->guildeqid; strcpy(gc->Inviter, sgc->target); strcpy(gc->Invitee, sgc->from); client->QueuePacket(outapp); /* if (client->SetGuild(sgc->guilddbid, GUILD_MAX_RANK)) worldserver.SendEmoteMessage(0, sgc->guilddbid, MT_Guild, "%s has joined the guild. Rank: %s.", client->GetName(), guilds[sgc->guildeqid].rank[GUILD_MAX_RANK].rankname); else worldserver.SendEmoteMessage(sgc->from, 0, 0, "Guild invite failed."); */ } break; } case ServerOP_GuildRemove: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (client == 0) { // do nothing } else if ((!guilds[sgc->guildeqid].rank[sgc->fromrank].remove) && !(strcasecmp(sgc->from, sgc->target) == 0)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You dont have permission to remove."); } else if (client->GuildDBID() != sgc->guilddbid) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is not in your guild.", client->GetName()); } else if (client->GuildRank() <= sgc->fromrank && !(sgc->fromaccountid == guilds[sgc->guildeqid].leader) && !(strcasecmp(sgc->from, sgc->target) == 0)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s's rank is too high for you to remove them.", client->GetName()); } else { if (client->SetGuild(0, GUILD_MAX_RANK)) { if (strcasecmp(sgc->from, sgc->target) == 0) { worldserver.SendEmoteMessage(0, sgc->guilddbid, GUILD, "%s has left the guild.", client->GetName()); } else { worldserver.SendEmoteMessage(0, sgc->guilddbid, GUILD, "%s has been removed from the guild by %s.", client->GetName(), sgc->from); client->Message(GUILD, "You have been removed from the guild by %s.", sgc->from); } } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Guild remove failed."); } } break; } case ServerOP_GuildPromote: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (client == 0) { // do nothing } else if (client->GuildDBID() != sgc->guilddbid) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is not in your guild.", client->GetName()); } else if ((!guilds[sgc->guildeqid].rank[sgc->fromrank].promote) && !(strcasecmp(sgc->from, sgc->target) == 0)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You dont have permission to promote."); } else if (client->GuildDBID() != sgc->guilddbid) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s isnt in your guild.", client->GetName()); } else if (client->GuildRank() <= sgc->newrank) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is already rank %i.", client->GetName(), client->GuildRank()); } else if (sgc->newrank <= sgc->fromrank && sgc->fromaccountid != guilds[sgc->guildeqid].leader) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You cannot promote people to a greater or equal rank than yourself."); } else { if (client->SetGuild(sgc->guilddbid, sgc->newrank)) { worldserver.SendEmoteMessage(0, sgc->guilddbid, MESSAGETYPE_Guild, "%s has been promoted to %s by %s.", client->GetName(), guilds[sgc->guildeqid].rank[sgc->newrank].rankname, sgc->from); } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Guild promote failed"); } } break; } case ServerOP_GuildDemote: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); zgm.LoadGuilds(); Guild_Struct* guilds = zgm.GetGuildList(); if (client == 0) { // do nothing } else if (client->GuildDBID() != sgc->guilddbid) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is not in your guild.", client->GetName()); } else if (!guilds[sgc->guildeqid].rank[sgc->fromrank].demote) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You dont have permission to demote."); } else if (client->GuildRank() >= sgc->newrank) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "%s is already rank %i.", client->GetName(), client->GuildRank()); } else if (sgc->newrank <= sgc->fromrank && sgc->fromaccountid != guilds[sgc->guildeqid].leader && !(strcasecmp(sgc->from, sgc->target) == 0)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "You cannot demote people with a greater or equal rank than yourself."); } else { if (client->SetGuild(sgc->guilddbid, sgc->newrank)) { worldserver.SendEmoteMessage(0, sgc->guilddbid, MESSAGETYPE_Guild, "%s has been demoted to %s by %s.", client->GetName(), guilds[sgc->guildeqid].rank[sgc->newrank].rankname, sgc->from); } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Guild demote failed"); } } break; } case ServerOP_GuildGMSet: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); if (client != 0) { if (client->GuildDBID() == 0 || sgc->guilddbid == 0) { if (!client->SetGuild(sgc->guilddbid, GUILD_MAX_RANK)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Error: Guild #%i not found", sgc->guilddbid); } } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Error: %s is already in a guild", sgc->target); } } break; } case ServerOP_GuildGMSetRank: { ServerGuildCommand_Struct* sgc = (ServerGuildCommand_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(sgc->target); if (client != 0) { if (client->GuildDBID() != 0) { if (!client->SetGuild(client->GuildDBID(), sgc->newrank)) { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Error: SetRank failed.", sgc->guilddbid); } } else { worldserver.SendEmoteMessage(sgc->from, 0, 0, "Error: %s is not in a guild", sgc->target); } } break; } /* case ServerOP_GuildCreateResponse: { GuildCreateResponse_Struct* gcrs = (GuildCreateResponse_Struct*) pack->pBuffer; if(gcrs->Created) { cout << "Guild " << gcrs->GuildName << " created." << endl; Client* client = entity_list.GetClientByName(gcrs->LeaderCharName); // invite the client to guild zgm.InviteToGuild(0, gcrs->eqid, client, client, GuildLeader); } break; }*/ case ServerOP_FlagUpdate: { Client* client = entity_list.GetClientByAccID(Database::Instance()->GetAccountIDByName((char*) pack->pBuffer)); if (client != 0) { client->UpdateAdmin(); } break; } case ServerOP_GMGoto: { if (pack->size != sizeof(ServerGMGoto_Struct)) { cout << "Wrong size on ServerOP_GMGoto. Got: " << pack->size << ", Expected: " << sizeof(ServerGMGoto_Struct) << endl; break; } if (!ZoneLoaded) { break; } ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(gmg->gotoname); if (client != 0) { worldserver.SendEmoteMessage(gmg->myname, 0, 13, "Summoning you to: %s @ %s, %1.1f, %1.1f, %1.1f", client->GetName(), zone->GetShortName(), client->GetX(), client->GetY(), client->GetZ()); ServerPacket* outpack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); outpack->pBuffer = new uchar[outpack->size]; memset(outpack->pBuffer, 0, outpack->size); ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) outpack->pBuffer; strcpy(szp->adminname, gmg->myname); strcpy(szp->name, gmg->myname); strcpy(szp->zone, zone->GetShortName()); szp->x_pos = client->GetX(); szp->y_pos = client->GetY(); szp->z_pos = client->GetZ(); worldserver.SendPacket(outpack); safe_delete(outpack);//delete outpack; } else { worldserver.SendEmoteMessage(gmg->myname, 0, 13, "Error: %s not found", gmg->gotoname); } break; } case ServerOP_MultiLineMsg: { ServerMultiLineMsg_Struct* mlm = (ServerMultiLineMsg_Struct*) pack->pBuffer; Client* client = entity_list.GetClientByName(mlm->to); if (client) { APPLAYER* outapp = new APPLAYER(OP_MultiLineMsg, strlen(mlm->message)); strcpy((char*) outapp->pBuffer, mlm->message); client->QueuePacket(outapp); safe_delete(outapp);//delete outapp; } break; } case ServerOP_RezzPlayer: { RezzPlayer_Struct* srs = (RezzPlayer_Struct*)pack->pBuffer; //Yeahlight: A resurrection request has been made if(srs->rezzopcode == OP_RezzRequest) { Client* client = entity_list.GetClientByName(srs->owner); //Yeahlight: Owner of the corpse is online if(client) { Spell* spell = spells_handler.GetSpellPtr(srs->rez.spellID); //Yeahlight: Spell passed through the packet is a legit spell if(spell) { //Yeahlight: Record the pending resurrection information client->SetPendingRez(true); client->SetPendingRezExp(srs->exp); client->SetPendingCorpseID(srs->corpseDBID); client->SetPendingRezX(srs->rez.x); client->SetPendingRezY(srs->rez.y); client->SetPendingRezZ(srs->rez.z); client->SetPendingRezZone(srs->rez.zoneName); client->SetPendingSpellID(spell->GetSpellID()); client->StartPendingRezTimer(); if(client->GetDebugMe()) client->Message(YELLOW, "Debug: Forwarding the resurrection request to your client (%s)", srs->rez.targetName); //Yeahlight: Forward the resurrection packet to the corpse's owner APPLAYER* outapp = new APPLAYER(OP_RezzRequest, sizeof(Resurrect_Struct)); Resurrect_Struct* rez = (Resurrect_Struct*)outapp->pBuffer; memset(rez, 0, sizeof(Resurrect_Struct)); memcpy(rez, &srs->rez, sizeof(Resurrect_Struct)); client->QueuePacket(outapp); safe_delete(outapp); } } } //Yeahlight: A resurrection confirmation has been made else if(srs->rezzopcode == OP_RezzAnswer) { Client* client = entity_list.GetClientByName(srs->owner); //Yeahlight: Owner of the corpse is online if(client) { bool fullGMRez = false; //Yeahlight: The corpse owner answers 'yes' to the request if(srs->action == 1) { Database::Instance()->SetCorpseRezzed(client->GetPendingCorpseID()); //Yeahlight: Player casted resurrection if(client->GetPendingSpellID() != 994) { float expRefund = 0.00; //Yeahlight: PC has exp on the corpse if(client->GetPendingRezExp()) { //Yeahlight: Switch based on spell ID switch(client->GetPendingSpellID()) { //Yeahlight: Revive case 391: { expRefund = 0.00; break; } //Yeahlight: Resuscitate case 388: { expRefund = 0.50; break; } //Yeahlight: Resurrection case 392: { expRefund = 0.90; break; } //Yeahlight: Reviviscence case 1524: { expRefund = 0.96; break; } //Yeahlight: Convergence case 1733: { expRefund = 0.93; break; } default: { client->Message(RED, "ERROR: Unknown resurrection spell ID: %i", client->GetPendingSpellID()); expRefund = 0.00; } } if(client->GetDebugMe()) client->Message(LIGHTEN_BLUE, "Debug: Your resurrection return on exp: %1.2f", expRefund); client->AddEXP(client->GetPendingRezExp() * expRefund, true); } } //Yeahlight: GM casted resurrection else { fullGMRez = true; if(client->GetDebugMe()) client->Message(LIGHTEN_BLUE, "Debug: Your resurrection return on exp: 1.00"); client->AddEXP(client->GetPendingRezExp(), true); } //Yeahlight: Client is being resurrected in another zone; prepare them for transit if(strcmp(zone->GetShortName(), srs->rez.zoneName) != 0) { client->SetTempHeading(0); client->SetUsingSoftCodedZoneLine(true); client->SetIsZoning(true); client->SetZoningX(client->GetPendingRezX()); client->SetZoningY(client->GetPendingRezY()); client->SetZoningZ(client->GetPendingRezZ()); } //Yeahlight: Send the packet back to the owner of the corpse APPLAYER* outapp = new APPLAYER(OP_RezzComplete, sizeof(Resurrect_Struct)); memcpy(outapp->pBuffer, &srs->rez, sizeof(Resurrect_Struct)); srs->rez.fullGMRez = fullGMRez; client->QueuePacket(outapp); safe_delete(outapp); } //Yeahlight: The corpse owner answers 'no' to the request else if(srs->action == 0) { client->Message(BLACK, "You decline the request to be resurrected."); client->SetPendingRez(false); client->SetPendingRezExp(0); } } } break; } case ServerOP_Uptime: { if (pack->size != sizeof(ServerUptime_Struct)) { cout << "Wrong size on ServerOP_Uptime. Got: " << pack->size << ", Expected: " << sizeof(ServerUptime_Struct) << endl; break; } ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer; int32 ms = Timer::GetCurrentTime(); int32 d = ms / 86400000; ms -= d * 86400000; int32 h = ms / 3600000; ms -= h * 3600000; int32 m = ms / 60000; ms -= m * 60000; int32 s = ms / 1000; if (d) { this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02id %02ih %02im %02is", sus->zoneserverid, d, h, m, s); } else if (h) { this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02ih %02im %02is", sus->zoneserverid, h, m, s); } else { this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02im %02is", sus->zoneserverid, m, s); } break; } case ServerOP_Petition: { cout << "Got Server Requested Petition List Refresh" << endl; ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer; if (sus->status = 0) { petition_list.ReadDatabase(); } else if (sus->status = 1) { petition_list.ReadDatabase(); // Until I fix this to be better.... } break; } case ServerOP_RemoveBoat: // Tazadar (06/12/09) : We remove the boat from the zone { BoatName_Struct* bs = (BoatName_Struct*) pack->pBuffer; cout << "Trying to remove the boat : " << bs->boatname << endl; Mob * tmp = entity_list.GetMob(bs->boatname); if(tmp){ tmp->CastToNPC()->Depop(false); entity_list.RemoveNPC(tmp->CastToNPC()); } break; } case ServerOP_ZoneBoat : // Tazadar (06/16/09) : We teleport player to the other zone ! { cout << "A boat is zoning ! Teleporting clients !" << endl; ZoneBoat_Struct * zb = (ZoneBoat_Struct *) pack->pBuffer; Entity * tmp = 0; Mob * boat = entity_list.GetMob(zb->boatname); float xboat,yboat,zboat,headingboat; if(boat){ xboat = boat->GetX(); yboat = boat->GetY(); zboat = boat->GetZ();; headingboat = boat->GetHeading(); } else{ cerr << "Error in ServerOP_ZoneBoat boat : "<< zb->boatname << " does not exist."<<endl; break; } char * clients = (char *) pack->pBuffer; char zone[16] = ""; strcpy(zone, zb->zonename); char name[30]; float x,y,z,heading; for(int i=0 ; i < zb->numberOfPlayers ; i++){ memcpy(name,clients+sizeof(ZoneBoat_Struct)+30*i,30*sizeof(char)); cout << "Trying to teleport : "<< name << endl; tmp = entity_list.GetClientByName(name); if(tmp != 0 && tmp->IsClient()){ //cout << "ZonePC to " << zone << endl; Client * client = tmp->CastToClient(); heading = client->GetHeading()-headingboat; // Tazadar : Relative heading from the boat z = client->GetZ()-zboat; // Tazadar : Relative z from the boat client->GetRelativeCoordToBoat(client->GetY()-yboat,client->GetX()-xboat,(zb->heading-headingboat)*1.4,y,x); client->SetZoningHeading(zb->heading+heading); client->SetUsingSoftCodedZoneLine(true); client->SetIsZoning(true); client->SetZoningX(zb->x+x); client->SetZoningY(zb->y+y); client->SetZoningZ(zb->z+z); client->ZonePC(zone,0,0,10); } else{ // Tazadar : Player has crashed ? We remove it from boat infos // Tazadar : Make the packet for the World Serv ServerPacket* pack = new ServerPacket(ServerOP_BoatPL, sizeof(ServerBoat_Struct)); ServerBoat_Struct* servBoatInfos = (ServerBoat_Struct*) pack->pBuffer; // Tazadar : Fill the packet memcpy(servBoatInfos->player_name,name,sizeof(servBoatInfos->player_name)); // Tazadar : Send the packet worldserver.SendPacket(pack); } } break; } case ServerOP_SpawnBoat: // Tazadar (06/13/09) : We make the boat spawn before the zone in at the correct location. { SpawnBoat_Struct * bs = (SpawnBoat_Struct *) pack->pBuffer; Mob * tmp = 0; cout << "Spawning the boat :" << bs->boatname << "at loc " << bs->x <<","<< bs->y << "," << bs->z <<" heading " << bs->heading<<endl; //cout << "Loading boat from DB " << endl; string name = bs->boatname; name.resize(name.length()-2); NPCType boat; bool lineroute = false; Database::Instance()->LoadBoatData(name.c_str(),boat,lineroute); NPC* npc = new NPC(&boat, 0, bs->x, bs->y, bs->z, bs->heading); npc->SetLineRoute(lineroute); entity_list.AddNPC(npc); npc->SendPosUpdate(false); break; } case ServerOP_BoatGoTo : // Tazadar (06/14/09) : We make the boat move { BoatGoTo_Struct * gt = (BoatGoTo_Struct *) pack->pBuffer; cout << "World orders " << gt->boatname << " to go to node number " << gt->toNode << endl; Mob * tmp = entity_list.GetMob(gt->boatname); if(tmp && tmp->IsNPC()){ if(tmp->CastToNPC()->IsBoat()){ tmp->CastToNPC()->setBoatDestinationNode(gt->fromNode,gt->toNode); } else{ cerr << "Tried to give an order to the npc "<< gt->boatname <<" which is not a boat " << endl; } } else{ cerr << "Error in ServerOP_BoatGoTo boat " << gt->boatname << " does not exist"<<endl; } break; } case ServerOP_DayTime : // Kibanu - 7/30/2009 : Switch to day time for spawn data { if (ZoneLoaded) zone->SetTimeOfDay(true); break; } case ServerOP_NightTime : // Kibanu - 7/30/2009 : Switch to day time for spawn data { if (ZoneLoaded) zone->SetTimeOfDay(false); break; } case ServerOP_ZoneToZoneRequest: { if(pack->size != sizeof(ZoneToZone_Struct)) break; if (!ZoneLoaded) break; ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; if(ztz->current_zone_id == zone->GetZoneID()) { // it's a response Entity* entity = entity_list.GetClientByName(ztz->name); if(entity == 0) break; APPLAYER *outapp; outapp = new APPLAYER(OP_ZoneChange,sizeof(ZoneChange_Struct)); ZoneChange_Struct* zc2=(ZoneChange_Struct*)outapp->pBuffer; if(ztz->response == 0 || ztz->response == -1) { zc2->success = ZONE_ERROR_NOTREADY; entity->CastToMob()->SetZone(ztz->current_zone_id); } else { strncpy(zc2->char_name,entity->CastToMob()->GetName(),64); zc2->zoneID=ztz->requested_zone_id; zc2->success = 1; } entity->CastToClient()->QueuePacket(outapp); delete outapp; switch(ztz->response) { case -1: { entity->CastToMob()->Message(RED,"The zone is currently full, please try again later."); break; } case 0: { entity->CastToMob()->Message(RED,"All zone servers are taken at this time, please try again later."); break; } } } else { // it's a request if(zone->GetMaxClients() != 0 && numclients >= zone->GetMaxClients()) ztz->response = -1; else { ztz->response = 1; // since they asked about coming, lets assume they are on their way and not shut down. zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } SendPacket(pack); break; } break; } default: { cout << "Unknown ZSopcode:" << (int)pack->opcode; cout << "size:" << pack->size << endl; //DumpPacket(pack->pBuffer, pack->size); break; } } safe_delete(pack);//delete pack; //Yeahlight: Zone freeze debug if(ZONE_FREEZE_DEBUG && rand()%ZONE_FREEZE_DEBUG == 1) EQC_FREEZE_DEBUG(__LINE__, __FILE__); } return; }