void Client::SendPathPacket(const std::vector<FindPerson_Point> &points) { EQ::BackgroundTask task([](EQEmu::Any &data) { auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data); CullPoints(points); }, [this](EQEmu::Any &data) { auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data); if (points.size() < 2) { if (Admin() > 10) { Message(MT_System, "Too few points"); } EQApplicationPacket outapp(OP_FindPersonReply, 0); QueuePacket(&outapp); return; } if (points.size() > 36) { if (Admin() > 10) { Message(MT_System, "Too many points %u", points.size()); } EQApplicationPacket outapp(OP_FindPersonReply, 0); QueuePacket(&outapp); return; } if (Admin() > 10) { Message(MT_System, "Total points %u", points.size()); } int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point); auto outapp = new EQApplicationPacket(OP_FindPersonReply, len); FindPersonResult_Struct* fpr = (FindPersonResult_Struct*)outapp->pBuffer; std::vector<FindPerson_Point>::iterator cur, end; cur = points.begin(); end = points.end(); unsigned int r; for (r = 0; cur != end; ++cur, r++) { fpr->path[r] = *cur; } //put the last element into the destination field --cur; fpr->path[r] = *cur; fpr->dest = *cur; FastQueuePacket(&outapp); }, points); }
void MainView::Login() { string name, password; name = CLI::GetInput("用户名:"); password = CLI::GetInput("密码:"); if (!Data.VerifyUser(name, password)) { CLI::ShowMsg("用户名或密码错误!"); BOOST_LOG_TRIVIAL(warning) << "Log in failed, User Name:" << name; return; } model::User& user = Data.GetUser(name); if (user.isAdmin()) { AdministratorView Admin(user, &Data); while (Admin.Loop) Admin.Show(); CLI::CleanCLI(); } else { BankTellerView Teller(user, &Data); while (Teller.Loop) Teller.Show(); CLI::CleanCLI(); } }
bool Client::CanBeInZone() { //check some critial rules to see if this char needs to be booted from the zone //only enforce rules here which are serious enough to warrant being kicked from //the zone if(Admin() >= RuleI(GM, MinStatusToZoneAnywhere)) return(true); float safe_x, safe_y, safe_z; int16 minstatus = 0; uint8 minlevel = 0; char flag_needed[128]; if(!database.GetSafePoints(zone->GetShortName(), zone->GetInstanceVersion(), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) { //this should not happen... _log(CLIENT__ERROR, "Unable to query zone info for ourself '%s'", zone->GetShortName()); return(false); } if(GetLevel() < minlevel) { _log(CLIENT__ERROR, "Character does not meet min level requirement (%d < %d)!", GetLevel(), minlevel); return(false); } if(Admin() < minstatus) { _log(CLIENT__ERROR, "Character does not meet min status requirement (%d < %d)!", Admin(), minstatus); return(false); } if(flag_needed[0] != '\0') { //the flag needed string is not empty, meaning a flag is required. if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) { _log(CLIENT__ERROR, "Character does not have the flag to be in this zone (%s)!", flag_needed); return(false); } } return(true); }
static void give_money (dbref giver, dbref recipient, int key, int amount) { dbref aowner; int cost, pcost, rcost, aflags, dpamount; char *str; /* do amount consistency check */ if (amount < 0 && ((!Builder(giver) && !HasPriv(giver,recipient,POWER_STEAL,POWER3,NOTHING)) || DePriv(giver,recipient,DP_STEAL,POWER6,NOTHING))) { notify(giver, unsafe_tprintf("You look through your pockets. Nope, no negative %s.", mudconf.many_coins)); return; } if (!amount) { notify(giver, unsafe_tprintf("You must specify a positive number of %s.", mudconf.many_coins)); return; } dpamount = 0; if (amount < 0) dpamount = DePriv(giver,NOTHING,DP_NOSTEAL,POWER7,POWER_LEVEL_NA); else dpamount = DePriv(giver,NOTHING,DP_NOGOLD,POWER7,POWER_LEVEL_NA); if (dpamount) { if (DPShift(giver)) dpamount--; dpamount = mudconf.money_limit[dpamount]; } else dpamount = -1; if (!Admin(Owner(giver))) { if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > mudconf.paylimit)) { notify(giver, unsafe_tprintf("That player doesn't need that many %s!", mudconf.many_coins)); return; } if ((Typeof(recipient) != TYPE_PLAYER) && (!could_doit(giver, recipient, A_LUSE,1))) { notify(giver, unsafe_tprintf("%s won't take your money.", Name(recipient))); return; } } str = atr_get(Owner(giver), A_PAYLIM, &aowner, &aflags); pcost = atoi(str); free_lbuf(str); if (!Immortal(Owner(giver)) && pcost) { if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) && (Pennies(recipient) + amount > pcost)) { notify(giver, unsafe_tprintf("That player doesn't need that many %s!", mudconf.many_coins)); return; } else if (Pennies(recipient) + amount < (-pcost)) { notify(giver,"That player doesn't need that much debt!"); return; } } str = atr_get(Owner(recipient), A_RECEIVELIM, &aowner, &aflags); rcost = atoi(str); free_lbuf(str); if (!Immortal(Owner(giver)) && rcost) { if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) && (Pennies(recipient) + amount > rcost)) { notify(giver, unsafe_tprintf("That player doesn't need that many %s!", mudconf.many_coins)); return; } else if (Pennies(recipient) + amount < (-rcost)) { notify(giver,"That player doesn't need that much debt!"); return; } } if (!Immortal(Owner(giver))) { if (dpamount >= 0) { if (amount > 0) { if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > dpamount)) { notify(giver, unsafe_tprintf("That player doesn't need that many %s!", mudconf.many_coins)); return; } else if (amount > dpamount) { notify(giver, "Permission denied."); return; } } else { if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount < (-dpamount))) { notify(giver, unsafe_tprintf("That player doesn't need that many %s!", mudconf.many_coins)); return; } else if (amount < (-dpamount)) { notify(giver, "Permission denied."); return; } } } } /* try to do the give */ if (!payfor_give(giver, amount)) { notify(giver, unsafe_tprintf("You don't have that many %s to give!", mudconf.many_coins)); return; } /* Find out cost if an object */ if (Typeof(recipient) == TYPE_THING) { str = atr_pget(recipient, A_COST, &aowner, &aflags); cost = atoi(str); free_lbuf(str); /* Can't afford it? */ if (amount < cost) { notify(giver, "Feeling poor today?"); giveto(giver, amount, NOTHING); return; } /* Negative cost */ if (cost < 0) { return; } } else { cost = amount; } if (!(key & GIVE_QUIET)) { if (amount == 1) { notify(giver, unsafe_tprintf("You give a %s to %s.", mudconf.one_coin, Name(recipient))); notify_with_cause(recipient, giver, unsafe_tprintf("%s gives you a %s.", Name(giver), mudconf.one_coin)); } else { notify(giver, unsafe_tprintf("You give %d %s to %s.", amount, mudconf.many_coins, Name(recipient))); notify_with_cause(recipient, giver, unsafe_tprintf("%s gives you %d %s.", Name(giver), amount, mudconf.many_coins)); } } else { if (amount == 1) { notify(giver, unsafe_tprintf("You give a %s to %s. (quiet)", mudconf.one_coin, Name(recipient))); } else { notify(giver, unsafe_tprintf("You give %d %s to %s. (quiet)", amount, mudconf.many_coins, Name(recipient))); } } /* Report change given */ if((amount - cost) == 1) { notify(giver, unsafe_tprintf("You get 1 %s in change.", mudconf.one_coin)); giveto(giver, 1, NOTHING); } else if (amount != cost) { notify(giver, unsafe_tprintf("You get %d %s in change.", (amount - cost), mudconf.many_coins)); giveto(giver, (amount - cost), NOTHING); } if (pcost && (Pennies(Owner(recipient)) + cost > pcost)) { pcost = pcost - Pennies(Owner(recipient)); if (pcost < 0) pcost = 0; } else pcost = cost; if (!giveto(recipient, pcost, giver)) giveto(giver, cost, NOTHING); /* Transfer the money and run PAY attributes */ /* Rooms should not kick off the PAY attribute */ if ( !isRoom(giver) ) did_it(giver, recipient, A_PAY, NULL, A_OPAY, NULL, A_APAY, (char **)NULL, 0); return; }
void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { #ifdef BOTS // This block is necessary to clean up any bot objects owned by a Client Bot::ProcessClientZoneChange(this); #endif zoning = true; if (app->size != sizeof(ZoneChange_Struct)) { LogFile->write(EQEMuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct)); return; } #if EQDEBUG >= 5 LogFile->write(EQEMuLog::Debug, "Zone request from %s", GetName()); DumpPacket(app); #endif ZoneChange_Struct* zc=(ZoneChange_Struct*)app->pBuffer; uint16 target_zone_id = 0; uint16 target_instance_id = zc->instanceID; ZonePoint* zone_point = nullptr; //figure out where they are going. if(zc->zoneID == 0) { //client dosent know where they are going... //try to figure it out for them. switch(zone_mode) { case EvacToSafeCoords: case ZoneToSafeCoords: //going to safe coords, but client dosent know where? //assume it is this zone for now. target_zone_id = zone->GetZoneID(); break; case GMSummon: target_zone_id = zonesummon_id; break; case GateToBindPoint: target_zone_id = m_pp.binds[0].zoneId; break; case ZoneToBindPoint: target_zone_id = m_pp.binds[0].zoneId; break; case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going. target_zone_id = zonesummon_id; break; case ZoneUnsolicited: //client came up with this on its own. zone_point = zone->GetClosestZonePointWithoutZone(GetX(), GetY(), GetZ(), this, ZONEPOINT_NOZONE_RANGE); if(zone_point) { //we found a zone point, which is a reasonable distance away //assume that is the one were going with. target_zone_id = zone_point->target_zone_id; target_instance_id = zone_point->target_zone_instance; } else { //unable to find a zone point... is there anything else //that can be a valid un-zolicited zone request? CheatDetected(MQZone, zc->x, zc->y, zc->z); Message(13, "Invalid unsolicited zone request."); LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; } break; default: break; }; } else { // This is to allow both 6.2 and Titanium clients to perform a proper zoning of the client when evac/succor // WildcardX 27 January 2008 if(zone_mode == EvacToSafeCoords && zonesummon_id > 0) target_zone_id = zonesummon_id; else target_zone_id = zc->zoneID; //if we are zoning to a specific zone unsolicied, //then until otherwise determined, they must be zoning //on a zone line. if(zone_mode == ZoneUnsolicited) { if(target_zone_id == zone->GetZoneID()) { SendZoneCancel(zc); return; } zone_point = zone->GetClosestZonePoint(GetX(), GetY(), GetZ(), target_zone_id, this, ZONEPOINT_ZONE_RANGE); //if we didnt get a zone point, or its to a different zone, //then we assume this is invalid. if(!zone_point || zone_point->target_zone_id != target_zone_id) { LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); CheatDetected(MQGate, zc->x, zc->y, zc->z); SendZoneCancel(zc); return; } } } if(target_instance_id > 0) { //make sure we are in it and it's unexpired. if(!database.VerifyInstanceAlive(target_instance_id, CharacterID())) { Message(13, "Instance ID was expired or you were not in it."); SendZoneCancel(zc); return; } if(!database.VerifyZoneInstance(target_zone_id, target_instance_id)) { Message(13, "Instance ID was %u does not go with zone id %u", target_instance_id, target_zone_id); SendZoneCancel(zc); return; } } //make sure its a valid zone. const char *target_zone_name = database.GetZoneName(target_zone_id); if(target_zone_name == nullptr) { //invalid zone... Message(13, "Invalid target zone ID."); LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; } //load up the safe coords, restrictions, and verify the zone name float safe_x, safe_y, safe_z; int16 minstatus = 0; uint8 minlevel = 0; char flag_needed[128]; if(!database.GetSafePoints(target_zone_name, database.GetInstanceVersion(target_instance_id), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) { //invalid zone... Message(13, "Invalid target zone while getting safe points."); LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name); SendZoneCancel(zc); return; } char buf[10]; snprintf(buf, 9, "%d", target_zone_id); buf[9] = '\0'; parse->EventPlayer(EVENT_ZONE, this, buf, 0); //handle circumvention of zone restrictions //we need the value when creating the outgoing packet as well. uint8 ignorerestrictions = zonesummon_ignorerestrictions; zonesummon_ignorerestrictions = 0; float dest_x=0, dest_y=0, dest_z=0, dest_h; dest_h = GetHeading(); switch(zone_mode) { case EvacToSafeCoords: case ZoneToSafeCoords: LogFile->write(EQEMuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id); dest_x = safe_x; dest_y = safe_y; dest_z = safe_z; break; case GMSummon: dest_x = zonesummon_x; dest_y = zonesummon_y; dest_z = zonesummon_z; ignorerestrictions = 1; break; case GateToBindPoint: dest_x = m_pp.binds[0].x; dest_y = m_pp.binds[0].y; dest_z = m_pp.binds[0].z; break; case ZoneToBindPoint: dest_x = m_pp.binds[0].x; dest_y = m_pp.binds[0].y; dest_z = m_pp.binds[0].z; ignorerestrictions = 1; //can always get to our bind point? seems exploitable break; case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going. //recycle zonesummon variables dest_x = zonesummon_x; dest_y = zonesummon_y; dest_z = zonesummon_z; break; case ZoneUnsolicited: //client came up with this on its own. //client requested a zoning... what are the cases when this could happen? //Handle zone point case: if(zone_point != nullptr) { //they are zoning using a valid zone point, figure out coords //999999 is a placeholder for 'same as where they were from' if(zone_point->target_x == 999999) dest_x = GetX(); else dest_x = zone_point->target_x; if(zone_point->target_y == 999999) dest_y = GetY(); else dest_y = zone_point->target_y; if(zone_point->target_z == 999999) dest_z=GetZ(); else dest_z = zone_point->target_z; if(zone_point->target_heading == 999) dest_h = GetHeading(); else dest_h = zone_point->target_heading; break; } //for now, there are no other cases... //could not find a valid reason for them to be zoning, stop it. CheatDetected(MQZoneUnknownDest, 0.0, 0.0, 0.0); LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name); SendZoneCancel(zc); return; default: break; }; //OK, now we should know where were going... //Check some rules first. int8 myerror = 1; //1 is succes //not sure when we would use ZONE_ERROR_NOTREADY //enforce min status and level if (!ignorerestrictions && (Admin() < minstatus || GetLevel() < minlevel)) { myerror = ZONE_ERROR_NOEXPERIENCE; } if(!ignorerestrictions && flag_needed[0] != '\0') { //the flag needed string is not empty, meaning a flag is required. if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id)) { Message(13, "You do not have the flag to enter %s.", target_zone_name); myerror = ZONE_ERROR_NOEXPERIENCE; } } //TODO: ADVENTURE ENTRANCE CHECK if(myerror == 1) { //we have successfully zoned DoZoneSuccess(zc, target_zone_id, target_instance_id, dest_x, dest_y, dest_z, dest_h, ignorerestrictions); } else { LogFile->write(EQEMuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name); SendZoneError(zc, myerror); } }