bool HkAddCheaterLog(const wstring &wscCharname, const wstring &wscReason) { FILE *f = fopen(("./flhook_logs/flhook_cheaters.log"), "at"); if(!f) return false; CAccount *acc = HkGetAccountByCharname(wscCharname); wstring wscAccountDir = L"???"; wstring wscAccountID = L"???"; if(acc) { HkGetAccountDirName(acc, wscAccountDir); wscAccountID = HkGetAccountID(acc); } uint iClientID = HkGetClientIdFromCharname(wscCharname); wstring wscHostName = L"???"; wstring wscIp = L"???"; if(iClientID != -1) { wscHostName = ClientInfo[iClientID].wscHostname; HkGetPlayerIP(iClientID,wscIp); } time_t tNow = time(0); struct tm *stNow = localtime(&tNow); fprintf(f, "%.2d/%.2d/%.4d %.2d:%.2d:%.2d Possible cheating detected (%s) by %s(%s)(%s) [%s %s]\n", stNow->tm_mon + 1, stNow->tm_mday, stNow->tm_year + 1900, stNow->tm_hour, stNow->tm_min, stNow->tm_sec, wstos(wscReason).c_str(), wstos(wscCharname).c_str(), wstos(wscAccountDir).c_str(), wstos(wscAccountID).c_str(), wstos(wscHostName).c_str(), wstos(wscIp).c_str()); fclose(f); return true; }
HK_ERROR HkGetAccountDirName(const wstring &wscCharname, wstring &wscDir) { HK_GET_CLIENTID(iClientID, wscCharname); CAccount *acc; if(iClientID != -1) acc = Players.FindAccountFromClientID(iClientID); else { if(!(acc = HkGetAccountByCharname(wscCharname))) return HKE_CHAR_DOES_NOT_EXIST; } return HkGetAccountDirName(acc, wscDir); }
/** Clean up old bounties **/ void CleanUpBounties() { conDebug(L"attempting to clean up bounties"); string File_FLHook_bounties = "..\\exe\\flhook_plugins\\bountytrackerbounties.cfg"; INI_Reader ini; if (ini.open(File_FLHook_bounties.c_str(), false)) { while (ini.read_header()) { if (ini.is_header("bounty")) { while (ini.read_value()) { if (ini.is_value("hit")) { wstring wscTargetName = stows(ini.get_value_string(0)); //if bounty has expired if ((uint)time(0) - stoi(mapBountyTargets[wscTargetName].issueTime) > iBountyAge) { conDebug(L"removing " + wscTargetName); //find bounty BountyTargetInfo BTIc = mapBountyTargets[wscTargetName]; //refund remaining credits to issuer HkAddCash(stows(BTIc.issuer), (stoi(BTIc.Cash) * stoi(BTIc.xTimes)));//issuer needs to be online(?) //notify issuer their bounty has been refunded //delete bounty deleteBountyCfg(BTIc); } //if target has changed name CAccount *caTargetAcc = HkGetAccountByCharname(wscTargetName); int iTargetAcc = stoi(HkGetAccountID(caTargetAcc)); if (iTargetAcc == -1) { //find bounty BountyTargetInfo BTIc = mapBountyTargets[wscTargetName]; //refund remaining credits to issuer HkAddCash(stows(BTIc.issuer), (stoi(BTIc.Cash) * stoi(BTIc.xTimes)));//issuer needs to be online(?) //notify issuer their bounty has been refunded //delete bounty deleteBountyCfg(BTIc); } } } } } ini.close(); } }
void LoadDockInfo(uint client) { CLIENT_DATA &cd = clients[client]; // How many docking modules do we have? cd.iDockingModules = 0; cd.mapDockedShips.clear(); for (list<EquipDesc>::iterator item = Players[client].equipDescList.equip.begin(); item != Players[client].equipDescList.equip.end(); item++) { if (item->bMounted && item->iArchID == 0xB85AB480) { cd.iDockingModules++; } } // Load docked ships until we run out of docking module space. uint count = HookExt::IniGetI(client, "dock.docked_ships_count"); for (uint i=1; i<=count && cd.mapDockedShips.size()<=cd.iDockingModules; i++) { char key[100]; sprintf(key, "dock.docked_ship.%u", i); wstring charname = HookExt::IniGetWS(client, key); if (charname.length()) { if (HkGetAccountByCharname(charname)) { cd.mapDockedShips[charname] = charname; } } } cd.wscDockedWithCharname = HookExt::IniGetWS(client, "dock.docked_with_charname"); if (cd.wscDockedWithCharname.length()) cd.mobile_docked = true; cd.iLastBaseID = HookExt::IniGetI(client, "dock.last_base"); cd.iCarrierSystem = HookExt::IniGetI(client, "dock.carrier_system"); cd.vCarrierLocation.x = HookExt::IniGetF(client, "dock.carrier_pos.x"); cd.vCarrierLocation.y = HookExt::IniGetF(client, "dock.carrier_pos.y"); cd.vCarrierLocation.z = HookExt::IniGetF(client, "dock.carrier_pos.z"); Vector vRot; vRot.x = HookExt::IniGetF(client, "dock.carrier_rot.x"); vRot.y = HookExt::IniGetF(client, "dock.carrier_rot.y"); vRot.z = HookExt::IniGetF(client, "dock.carrier_rot.z"); cd.mCarrierLocation = EulerMatrix(vRot); }
/** Process a show cash command **/ bool GiveCash::UserCmd_ShowCash(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { // The last error. HK_ERROR err; // Get the current character name wstring wscCharname = (const wchar_t*) Players.GetActiveCharacterName(iClientID); // Get the parameters from the user command. wstring wscTargetCharname = GetParam(wscParam, L' ', 0); wstring wscCode = GetParam(wscParam, L' ', 1); if (!wscTargetCharname.length() || !wscCode.length()) { PrintUserCmdText(iClientID, L"ERR Invalid parameters"); PrintUserCmdText(iClientID, usage); return true; } CAccount *acc=HkGetAccountByCharname(wscTargetCharname); if (acc==0) { PrintUserCmdText(iClientID, L"ERR char does not exist"); return true; } string scFile; if (!GetUserFilePath(scFile, wscTargetCharname, "-givecash.ini")) return true; wstring wscTargetCode = IniGetWS(scFile, "Settings", "Code", L""); if (!wscTargetCode.length() || wscTargetCode!=wscCode) { PrintUserCmdText(iClientID, L"ERR cash account access denied"); return true; } int iCash = 0; if ((err = HkGetCash(wscTargetCharname, iCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } PrintUserCmdText(iClientID, L"OK Account "+wscTargetCharname+L" has " + ToMoneyStr(iCash) + L" credits"); return true; }
bool HkIsInCharSelectMenu(const wstring &wscCharname) { CAccount *acc = HkGetAccountByCharname(wscCharname); if(!acc) return false; uint iClientID = HkGetClientIdFromAccount(acc); if(iClientID == -1) return false; uint iBase = 0; uint iSystem = 0; pub::Player::GetBase(iClientID, iBase); pub::Player::GetSystem(iClientID, iSystem); if(!iBase && !iSystem) return true; else return false; }
EXPORT void IniSetS(const wstring &charname, const string &name, const string &value) { // If the player is online then update the in memory cache. string charfilename = GetCharfilename(charname) + ".fl"; for (map<uint, FLHOOK_PLAYER_DATA>::iterator i = clients.begin(); i != clients.end(); ++i) { if (i->second.charfilename == charfilename) { HookExt::IniSetS(i->first, name, value); return; } } // Otherwise write directly to the character file if it exists. CAccount *acc = HkGetAccountByCharname(charname); if (acc) { string charpath = scAcctPath + GetCharfilename(acc->wszAccID) + "\\" + charfilename; WritePrivateProfileString("flhook", name.c_str(), value.c_str(), charpath.c_str()); } }
uint HkGetClientIdFromCharname(const wstring &wscCharname) { CAccount *acc = HkGetAccountByCharname(wscCharname); if(!acc) return -1; uint iClientID = HkGetClientIdFromAccount(acc); if(iClientID == -1) return -1; wchar_t *wszActiveCharname = (wchar_t*)Players.GetActiveCharacterName(iClientID); if(!wszActiveCharname) return -1; wstring wscActiveCharname = wszActiveCharname; wscActiveCharname = ToLower(wscActiveCharname); if(wscActiveCharname.compare(ToLower(wscCharname)) != 0) return -1; return iClientID; }
bool UserCmd_BountyView(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { if (!bPluginEnabled) { PrintUserCmdText(iClientID, L"BountyTracker is disabled."); return true; } // Get the parameters from the user command. wstring wscName = GetParam(wscParam, L' ', 0); wstring wscCash = GetParam(wscParam, L' ', 1); wstring wscxTimes = GetParam(wscParam, L' ', 2); if (wscName == L"") { PrintUserCmdText(iClientID, L"ERR invalid Parameters\n"); return false; } if (HkGetAccountByCharname(wscName) == 0) { PrintUserCmdText(iClientID, L"ERR Player does not exist"); return true; } BountyTargetInfo BTIv = mapBountyTargets[ToLower(wscName)]; wstring PFwsTargetInfo; PFwsTargetInfo = L"Target: "; PFwsTargetInfo += ToLower(wscName); PFwsTargetInfo += L" Worth: "; PFwsTargetInfo += stows(BTIv.Cash); PFwsTargetInfo += L" Contracts Left: "; PFwsTargetInfo += stows(BTIv.xTimes); PFwsTargetInfo += L" Issuer: "; PFwsTargetInfo += stows(BTIv.issuer); PFwsTargetInfo += L" Issued: "; PFwsTargetInfo += stows(BTIv.issueTime); PrintUserCmdText(iClientID, PFwsTargetInfo); PrintUserCmdText(iClientID, L"OK"); return true; }
bool UserCmd_BountyAddTo(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { if (!bPluginEnabled) { PrintUserCmdText(iClientID, L"BountyTracker is disabled."); return true; } // Get the parameters from the user command. wstring wscName = GetParam(wscParam, L' ', 0); wstring wscCash = GetParam(wscParam, L' ', 1); wstring wscxTimes = GetParam(wscParam, L' ', 2); wscCash = ReplaceStr(wscCash, L".", L""); wscCash = ReplaceStr(wscCash, L",", L""); wscCash = ReplaceStr(wscCash, L"$", L""); wscCash = ReplaceStr(wscCash, L"e6", L"000000"); if (wscName == L"") { PrintUserCmdText(iClientID, L"ERR invalid name\n"); return false; } if (HkGetAccountByCharname(wscName) == 0) { PrintUserCmdText(iClientID, L"ERR Player does not exist"); return true; } if (wscCash == L"") { PrintUserCmdText(iClientID, L"ERR invalid cash amount\n"); return false; } if (stoi(wscCash) < 1000000) { PrintUserCmdText(iClientID, L"ERR bounty cannot be less than 1,000,000 s.c"); return true; } //get bounty BountyTargetInfo BTIat = mapBountyTargets[ToLower(wscName)]; //check if it is active if (!BTIat.active) { PrintUserCmdText(iClientID, L"ERR bounty not currently active"); return true; } //check user has enough money for the bounty int iCash; HkGetCash(stows(ToLower(wstos((wchar_t*)Players.GetActiveCharacterName(iClientID)))), iCash); if (iCash < (stoi(wscCash) * stoi(BTIat.xTimes))) { PrintUserCmdText(iClientID, L"ERR Not enough cash for bounty."); return true; } HkAddCash((wchar_t*)Players.GetActiveCharacterName(iClientID), 0 - (stoi(wscCash) * stoi(BTIat.xTimes))); if (deleteBountyCfg(BTIat)) { //ConPrint(L"bounty removed from cfg\n"); } else { ConPrint(L"BOUNTYTRACKER: Err removing from cfg. is server admin?\n"); } BTIat.Cash = itos(stoi(BTIat.Cash) + stoi(wscCash));//update cash bounty PrintUserCmdText(iClientID, L"Uploading to Neural Net..."); mapBountyTargets[ToLower(wscName)] = BTIat; if (appendBountyCfg(BTIat)) { //ConPrint(L"cfg saved\n"); } else { ConPrint(L"BOUNTYTRACKER: Err saving to cfg. is serevr admin?\n"); } PrintUserCmdText(iClientID, L"OK"); return true; }
bool UserCmd_BountyAdd(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { if (!bPluginEnabled) { PrintUserCmdText(iClientID, L"BountyTracker is disabled."); return true; } // Get the parameters from the user command. wstring wscName = GetParam(wscParam, L' ', 0); wstring wscCash = GetParam(wscParam, L' ', 1); wstring wscxTimes = GetParam(wscParam, L' ', 2); wscCash = ReplaceStr(wscCash, L".", L""); wscCash = ReplaceStr(wscCash, L",", L""); wscCash = ReplaceStr(wscCash, L"$", L""); wscCash = ReplaceStr(wscCash, L"e6", L"000000");//because scientific notation is cool int iOnlineSecs; HkGetOnLineTime((wchar_t*)Players.GetActiveCharacterName(iClientID), iOnlineSecs); if (iOnlineSecs < 7200)// 7200 = 2hrs { PrintUserCmdText(iClientID, L"ERR Char is too new"); return true; } //you are not allowed to create a bounty. ERR rank too low (note, find out what a good rank should be to have access to this. no fresh chars can //create bounties. this way we can protect against creating random fresh accs, tranferring cash, and setting copious amounts of bounties. if (wscName == L"") { PrintUserCmdText(iClientID, L"ERR invalid name\n"); return false; } if (HkGetAccountByCharname(wscName) == 0) { PrintUserCmdText(iClientID, L"ERR Player does not exist"); return true; } if (mapBountyTargets[ToLower(wscName)].active) { PrintUserCmdText(iClientID, L"ERR Player already has an active bounty\n"); return true; } if (mapBountyTargets[ToLower(wscName)].lastTime != "") { if ((stoi(mapBountyTargets[ToLower(wscName)].lastTime) + 3600) > (int)time(0)) { PrintUserCmdText(iClientID, L"ERR Player is protected\n"); PrintUserCmdText(iClientID, stows(itos((stoi(mapBountyTargets[ToLower(wscName)].lastTime) + 3600) - (int)time(0))) + L"'s remaining"); return true; } } if (iClientID == HkGetClientIdFromCharname(stows(mapBountyTargets[ToLower(wscName)].lastIssuer)))//not too sure about this { PrintUserCmdText(iClientID, L"ERR You cannot double a bounty on this player\n"); return true; } if (wscCash == L"") { PrintUserCmdText(iClientID, L"ERR invalid cash amount\n"); return false; } if (wscxTimes == L"") { PrintUserCmdText(iClientID, L"ERR invalid contract limit\n"); return false; } if (stoi(wscCash) < 1000000) { PrintUserCmdText(iClientID, L"ERR bounty cannot be less than 1,000,000 s.c"); return true; } if (stoi(wscxTimes) < 0 || stoi(wscxTimes) > 5) { PrintUserCmdText(iClientID, L"ERR bounty contract limit cannot be less than 0 or more than 5"); return true; } BountyTargetInfo BTIa = mapBountyTargets[ToLower(wscName)]; //generate new bounty map values BTIa.Char = ToLower(wstos(wscName)); BTIa.Cash = wstos(wscCash); BTIa.xTimes = wstos(wscxTimes); BTIa.issuer = ToLower(wstos((wchar_t*)Players.GetActiveCharacterName(iClientID))); BTIa.lastIssuer = BTIa.issuer; BTIa.active = true; BTIa.lastTime = ""; BTIa.issueTime = itos((int)time(0)); //check user has enough money for the bounty int iCash; HkGetCash(stows(BTIa.issuer), iCash); if (iCash < (stoi(BTIa.Cash) * stoi(BTIa.xTimes))) { PrintUserCmdText(iClientID, L"ERR Not enough cash for bounty."); return true; } HkAddCash((wchar_t*)Players.GetActiveCharacterName(iClientID), 0 - (stoi(BTIa.Cash) * stoi(BTIa.xTimes))); PrintUserCmdText(iClientID, L"Uploading to Neural Net..."); mapBountyTargets[ToLower(wscName)] = BTIa; wstring PFwsTargetInfo; PFwsTargetInfo = L"Target: "; PFwsTargetInfo += ToLower(wscName); PFwsTargetInfo += L" Worth: "; PFwsTargetInfo += stows(BTIa.Cash); PFwsTargetInfo += L" Contracts Left: "; PFwsTargetInfo += stows(BTIa.xTimes); PFwsTargetInfo += L" Issuer: "; PFwsTargetInfo += stows(BTIa.issuer); PFwsTargetInfo += L" Issued: "; PFwsTargetInfo += stows(BTIa.issueTime); PrintUserCmdText(iClientID, PFwsTargetInfo); if (appendBountyCfg(BTIa)) { ConPrint(L"cfg saved\n"); } else { ConPrint(L"Err saving to cfg\n"); } PrintUserCmdText(iClientID, L"OK"); return true; }
/** Process a draw cash command **/ bool GiveCash::UserCmd_DrawCash(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { // The last error. HK_ERROR err; // Get the current character name wstring wscCharname = (const wchar_t*) Players.GetActiveCharacterName(iClientID); // Get the parameters from the user command. wstring wscTargetCharname = GetParam(wscParam, L' ', 0); wstring wscCode = GetParam(wscParam, L' ', 1); wstring wscCash = GetParam(wscParam, L' ', 2); wscCash = ReplaceStr(wscCash, L".", L""); wscCash = ReplaceStr(wscCash, L",", L""); wscCash = ReplaceStr(wscCash, L"$", L""); int cash = ToInt(wscCash); if (!wscTargetCharname.length() || !wscCode.length() || cash<=0) { PrintUserCmdText(iClientID, L"ERR Invalid parameters"); PrintUserCmdText(iClientID, usage); return true; } CAccount *iTargetAcc=HkGetAccountByCharname(wscTargetCharname); if (iTargetAcc==0) { PrintUserCmdText(iClientID, L"ERR char does not exist"); return true; } int secs = 0; HkGetOnLineTime(wscTargetCharname, secs); if (secs<set_iMinTime) { PrintUserCmdText(iClientID, L"ERR insufficient time online"); return true; } if (InBlockedSystem(wscCharname) || InBlockedSystem(wscTargetCharname)) { PrintUserCmdText(iClientID, L"ERR cash transfer blocked"); return true; } string scFile; if (!GetUserFilePath(scFile, wscTargetCharname, "-givecash.ini")) return true; wstring wscTargetCode = IniGetWS(scFile, "Settings", "Code", L""); if (!wscTargetCode.length() || wscTargetCode!=wscCode) { PrintUserCmdText(iClientID, L"ERR cash account access denied"); return true; } if (cash<set_iMinTransfer || cash<0) { PrintUserCmdText(iClientID, L"ERR Transfer too small, minimum transfer "+ToMoneyStr(set_iMinTransfer)+L" credits"); return true; } int tCash = 0; if ((err = HkGetCash(wscTargetCharname, tCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if (tCash<cash) { PrintUserCmdText(iClientID, L"ERR Insufficient credits"); return true; } // Check the adding this cash to this player will not // exceed the maximum ship value. float fTargetValue = 0.0f; if (HKGetShipValue(wscCharname, fTargetValue) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if ((fTargetValue + cash) > 2000000000.0f) { PrintUserCmdText(iClientID, L"ERR Transfer will exceed credit limit"); return true; } // Calculate the new cash int iExpectedCash = 0; if ((err = HkGetCash(wscCharname, iExpectedCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } iExpectedCash += cash; // Do an anticheat check on the receiving ship first. if (HkAntiCheat(iClientID) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when drawing %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str()); return true; } HkSaveChar(iClientID); uint targetClientId = HkGetClientIdFromCharname(wscTargetCharname); if (targetClientId != -1) { if (ClientInfo[iClientID].iTradePartner || ClientInfo[targetClientId].iTradePartner) { PrintUserCmdText(iClientID, L"ERR Trade window open"); AddLog("NOTICE: Trade window open when drawing %s credits from %s (%s) to %s (%s) %u %u", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), iClientID, targetClientId); return true; } } // Remove cash from target character if ((err = HkAddCash(wscTargetCharname, 0-cash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if (targetClientId!=-1 && !HkIsInCharSelectMenu(targetClientId)) { if (HkAntiCheat(targetClientId) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when drawing %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str()); return true; } HkSaveChar(targetClientId); } // Add cash to this player if ((err = HkAddCash(wscCharname, cash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if (HkAntiCheat(iClientID) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when drawing %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str()); return true; } HkSaveChar(iClientID); // Check that receiving player has the correct ammount of cash. int iCurrCash; if ((err = HkGetCash(wscCharname, iCurrCash)) != HKE_OK || iCurrCash != iExpectedCash) { AddLog("ERROR: Cash transfer error when drawing %s credits from %s (%s) to %s (%s) current %s credits expected %s credits ", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(ToMoneyStr(iCurrCash)).c_str(), wstos(ToMoneyStr(iExpectedCash)).c_str()); PrintUserCmdText(iClientID, L"ERR Transfer failed"); } // If the target player is online then send them a message saying // telling them that they've received transfered cash. wstring msg = L"You have transferred " + ToMoneyStr(cash) + L" credits to " + wscCharname; if (targetClientId!=-1 && !HkIsInCharSelectMenu(targetClientId)) { PrintUserCmdText(targetClientId, L"%s", msg.c_str()); } // Otherwise we assume that the character is offline so we record an entry // in the character's givecash.ini. When they come online we inform them // of the transfer. The ini is cleared when ever the character logs in. else { LogTransfer(wscTargetCharname, msg); } AddLog("NOTICE: Draw %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str()); // A friendly message explaining the transfer. msg = GetTimeString(set_bLocalTime) + L": You have drawn " + ToMoneyStr(cash) + L" credits from " + wscTargetCharname; PrintUserCmdText(iClientID, L"%s", msg.c_str()); return true; }
/** Process a give cash command */ bool GiveCash::UserCmd_GiveCash(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { // The last error. HK_ERROR err; // Get the current character name wstring wscCharname = (const wchar_t*) Players.GetActiveCharacterName(iClientID); // Get the parameters from the user command. wstring wscTargetCharname = GetParam(wscParam, L' ', 0); wstring wscCash = GetParam(wscParam, L' ', 1); wstring wscAnon = GetParam(wscParam, L' ', 2); wscCash = ReplaceStr(wscCash, L".", L""); wscCash = ReplaceStr(wscCash, L",", L""); wscCash = ReplaceStr(wscCash, L"$", L""); int cash = ToInt(wscCash); if ((!wscTargetCharname.length() || cash<=0) || (wscAnon.size() && wscAnon!=L"anon")) { PrintUserCmdText(iClientID, L"ERR Invalid parameters"); PrintUserCmdText(iClientID, usage); return true; } bool bAnon = false; if (wscAnon==L"anon") bAnon = true; if (HkGetAccountByCharname(wscTargetCharname)==0) { PrintUserCmdText(iClientID, L"ERR char does not exist"); return true; } int secs = 0; HkGetOnLineTime(wscCharname, secs); if (secs<set_iMinTime) { PrintUserCmdText(iClientID, L"ERR insufficient time online"); return true; } if (InBlockedSystem(wscCharname) || InBlockedSystem(wscTargetCharname)) { PrintUserCmdText(iClientID, L"ERR cash transfer blocked"); return true; } // Read the current number of credits for the player // and check that the character has enough cash. int iCash = 0; if ((err = HkGetCash(wscCharname, iCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if (cash<set_iMinTransfer || cash<0) { PrintUserCmdText(iClientID, L"ERR Transfer too small, minimum transfer "+ToMoneyStr(set_iMinTransfer)+L" credits"); return true; } if (iCash<cash) { PrintUserCmdText(iClientID, L"ERR Insufficient credits"); return true; } // Prevent target ship from becoming corrupt. float fTargetValue = 0.0f; if (HKGetShipValue(wscTargetCharname, fTargetValue) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if ((fTargetValue + cash) > 2000000000.0f) { PrintUserCmdText(iClientID, L"ERR Transfer will exceed credit limit"); return true; } // Calculate the new cash int iExpectedCash = 0; if ((err = HkGetCash(wscTargetCharname, iExpectedCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Get cash failed err="+HkErrGetText(err)); return true; } iExpectedCash += cash; // Do an anticheat check on the receiving character first. uint targetClientId = HkGetClientIdFromCharname(wscTargetCharname); if (targetClientId!=-1 && !HkIsInCharSelectMenu(targetClientId)) { if (HkAntiCheat(targetClientId) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when sending %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str()); return true; } HkSaveChar(targetClientId); } if (targetClientId != -1) { if (ClientInfo[iClientID].iTradePartner || ClientInfo[targetClientId].iTradePartner) { PrintUserCmdText(iClientID, L"ERR Trade window open"); AddLog("NOTICE: Trade window open when sending %s credits from %s (%s) to %s (%s) %u %u", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), iClientID, targetClientId); return true; } } // Remove cash from current character and save it checking that the // save completes before allowing the cash to be added to the target ship. if ((err = HkAddCash(wscCharname, 0-cash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Remove cash failed err="+HkErrGetText(err)); return true; } if (HkAntiCheat(iClientID) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when sending %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str()); return true; } HkSaveChar(iClientID); // Add cash to target character if ((err = HkAddCash(wscTargetCharname, cash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Add cash failed err="+HkErrGetText(err)); return true; } targetClientId = HkGetClientIdFromCharname(wscTargetCharname); if (targetClientId!=-1 && !HkIsInCharSelectMenu(targetClientId)) { if (HkAntiCheat(targetClientId) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR Transfer failed"); AddLog("NOTICE: Possible cheating when sending %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str()); return true; } HkSaveChar(targetClientId); } // Check that receiving character has the correct ammount of cash. int iCurrCash; if ((err = HkGetCash(wscTargetCharname, iCurrCash)) != HKE_OK || iCurrCash != iExpectedCash) { AddLog("ERROR: Cash transfer error when sending %s credits from %s (%s) to %s (%s) current %s credits expected %s credits ", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str(), wstos(ToMoneyStr(iCurrCash)).c_str(), wstos(ToMoneyStr(iExpectedCash)).c_str()); PrintUserCmdText(iClientID, L"ERR Transfer failed"); return true; } // If the target player is online then send them a message saying // telling them that they've received the cash. wstring msg = L"You have received " + ToMoneyStr(cash) + L" credits from " + ((bAnon)?L"anonymous":wscCharname); if (targetClientId!=-1 && !HkIsInCharSelectMenu(targetClientId)) { PrintUserCmdText(targetClientId, L"%s", msg.c_str()); } // Otherwise we assume that the character is offline so we record an entry // in the character's givecash.ini. When they come online we inform them // of the transfer. The ini is cleared when ever the character logs in. else { wstring msg = L"You have received " + ToMoneyStr(cash) + L" credits from " + ((bAnon)?L"anonymous":wscCharname); LogTransfer(wscTargetCharname, msg); } AddLog("NOTICE: Send %s credits from %s (%s) to %s (%s)", wstos(ToMoneyStr(cash)).c_str(), wstos(wscCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscCharname))).c_str(), wstos(wscTargetCharname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(wscTargetCharname))).c_str()); // A friendly message explaining the transfer. msg = L"You have sent " + ToMoneyStr(cash) + L" credits to " + wscTargetCharname; if (bAnon) msg += L" anonymously"; PrintUserCmdText(iClientID, L"%s", msg.c_str()); return true; }
void Siege::SiegeGunDeploy(uint client, const wstring &args) { // Abort processing if this is not a "heavy lifter" uint shiparch; pub::Player::GetShipID(client, shiparch); if (set_construction_shiparch != 0 && shiparch != set_construction_shiparch) { PrintUserCmdText(client, L"ERR Need deployment ship"); return; } uint ship; pub::Player::GetShip(client, ship); if (!ship) { PrintUserCmdText(client, L"ERR Not in space"); return; } // If the ship is moving, abort the processing. Vector dir1; Vector dir2; pub::SpaceObj::GetMotion(ship, dir1, dir2); if (dir1.x>5 || dir1.y>5 || dir1.z>5) { PrintUserCmdText(client, L"ERR Ship is moving"); return; } int min = 100; int max = 5000; int randomsiegeint = min + (rand() % (int)(max - min + 1)); string randomname = "Siege Cannon AX-" + randomsiegeint; // Check for conflicting base name if (GetPlayerBase(CreateID(PlayerBase::CreateBaseNickname(randomname).c_str()))) { PrintUserCmdText(client, L"ERR Deployment error, please reiterate."); return; } // Check that the ship has the requires commodities. int hold_size; list<CARGO_INFO> cargo; HkEnumCargo((const wchar_t*)Players.GetActiveCharacterName(client), cargo, hold_size); for (map<uint, uint>::iterator i = construction_items.begin(); i != construction_items.end(); ++i) { bool material_available = false; uint good = i->first; uint quantity = i->second; for (list<CARGO_INFO>::iterator ci = cargo.begin(); ci != cargo.end(); ++ci) { if (ci->iArchID == good && ci->iCount >= (int)quantity) { material_available = true; pub::Player::RemoveCargo(client, ci->iID, quantity); } } if (material_available == false) { PrintUserCmdText(client, L"ERR Construction failed due to insufficient raw material."); for (i = construction_items.begin(); i != construction_items.end(); ++i) { const GoodInfo *gi = GoodList::find_by_id(i->first); if (gi) { PrintUserCmdText(client, L"| %ux %s", i->second, HkGetWStringFromIDS(gi->iIDSName).c_str()); } } return; } } wstring charname = (const wchar_t*)Players.GetActiveCharacterName(client); AddLog("NOTICE: Base created %s by %s (%s)", randomname.c_str(), wstos(charname).c_str(), wstos(HkGetAccountID(HkGetAccountByCharname(charname))).c_str()); wstring password = L"hastesucks"; wstring basename = stows(randomname); PlayerBase *newbase = new PlayerBase(client, password, basename); player_bases[newbase->base] = newbase; newbase->basetype = "siegegun"; newbase->basesolar = "depot"; newbase->baseloadout = "depot"; newbase->defense_mode = 1; for (map<string, ARCHTYPE_STRUCT>::iterator iter = mapArchs.begin(); iter!=mapArchs.end(); iter++) { ARCHTYPE_STRUCT &thearch = iter->second; if (iter->first == newbase->basetype) { newbase->invulnerable = thearch.invulnerable; newbase->logic = thearch.logic; } } newbase->Spawn(); newbase->Save(); PrintUserCmdText(client, L"OK: Siege Cannon deployed"); PrintUserCmdText(client, L"Default administration password is %s", password.c_str()); }
bool UserCmd_RenameMe(uint iClientID, const wstring &wscCmd, const wstring &wscParam, const wchar_t *usage) { HK_ERROR err; // Don't indicate an error if moving is disabled. if (!set_bEnableRenameMe) return false; // Indicate an error if the command does not appear to be formatted correctly // and stop processing but tell FLHook that we processed the command. if (wscParam.size()==0) { PrintUserCmdText(iClientID, L"ERR Invalid parameters"); PrintUserCmdText(iClientID, usage); return true; } uint iBaseID; pub::Player::GetBase(iClientID, iBaseID); if (!iBaseID) { PrintUserCmdText(iClientID, L"ERR Not in base"); return true; } // If the new name contains spaces then flag this as an // error. wstring wscNewCharname = Trim(GetParam(wscParam, L' ', 0)); // Get the character name for this connection. wstring wscCharname = (const wchar_t*)Players.GetActiveCharacterName(iClientID); for (map<wstring, LockedShipsStruct>::iterator i = MapLockedShips.begin(); i != MapLockedShips.end(); ++i) { if ((i->first == wscCharname) && (i->second.LockLevel > 0)) { PrintUserCmdText(iClientID, L"ERR This ship is locked. The FBI has been notified."); wstring spurdoip; HkGetPlayerIP(iClientID, spurdoip); AddLog("SHIPLOCK: Attempt to rename locked ship %s from IP %s", wstos(wscCharname).c_str(), wstos(spurdoip).c_str()); ConPrint(L"SHIPLOCK: Attempt to rename locked ship %s from IP %s\n", wscCharname.c_str(), spurdoip.c_str()); return true; } } if (wscNewCharname.find(L" ")!=-1) { PrintUserCmdText(iClientID, L"ERR Space characters not allowed in name"); return true; } if (HkGetAccountByCharname(wscNewCharname)) { PrintUserCmdText(iClientID, L"ERR Name already exists"); return true; } if (wscNewCharname.length() > 23) { PrintUserCmdText(iClientID, L"ERR Name to long"); return true; } if (wscNewCharname.length() < MIN_CHAR_TAG_LEN) { PrintUserCmdText(iClientID, L"ERR Name to short"); return true; } if (set_bCharnameTags) { wstring wscPassword = Trim(GetParam(wscParam, L' ', 1)); for (std::map<wstring, TAG_DATA>::iterator i = mapTagToPassword.begin(); i != mapTagToPassword.end(); ++i) { if (wscNewCharname.find(i->first)==0 && i->second.rename_password.size() != 0) { if (!wscPassword.length()) { PrintUserCmdText(iClientID, L"ERR Name starts with an owned tag. Password is required."); return true; } else if (wscPassword != i->second.master_password && wscPassword != i->second.rename_password) { PrintUserCmdText(iClientID, L"ERR Name starts with an owned tag. Password is wrong."); return true; } // Password is valid for owned tag. break; } } } // Saving the characters forces an anti-cheat checks and fixes // up a multitude of other problems. HkSaveChar(wscCharname); if (!HkIsValidClientID(iClientID)) return true; // Read the current number of credits for the player // and check that the character has enough cash. int iCash = 0; if ((err = HkGetCash(wscCharname, iCash)) != HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } if (set_iRenameCost>0 && iCash<set_iRenameCost) { PrintUserCmdText(iClientID, L"ERR Insufficient credits"); return true; } // Read the last time a rename was done on this character wstring wscDir; if ((err = HkGetAccountDirName(wscCharname, wscDir))!=HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } string scRenameFile = scAcctPath + wstos(wscDir) + "\\" + "rename.ini"; int lastRenameTime = IniGetI(scRenameFile, "General", wstos(wscCharname), 0); // If a rename was done recently by this player then reject the request. // I know that time() returns time_t...shouldn't matter for a few years // yet. if ((lastRenameTime + 300) < (int)time(0)) { if ((lastRenameTime + set_iRenameTimeLimit) > (int)time(0)) { PrintUserCmdText(iClientID, L"ERR Rename time limit"); return true; } } char szDataPath[MAX_PATH]; GetUserDataPath(szDataPath); string scAcctPath = string(szDataPath) + "\\Accts\\MultiPlayer\\"; wstring wscSourceFile; if ((err = HkGetCharFileName(wscCharname, wscSourceFile))!=HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } wstring wscDestFile; if ((err = HkGetCharFileName(wscNewCharname, wscDestFile))!=HKE_OK) { PrintUserCmdText(iClientID, L"ERR "+HkErrGetText(err)); return true; } // Remove cash if we're charging for it. if (set_iRenameCost>0) HkAddCash(wscCharname, 0-set_iRenameCost); RENAME o; o.wscCharname = wscCharname; o.wscNewCharname = wscNewCharname; o.scSourceFile = scAcctPath + wstos(wscDir) + "\\" + wstos(wscSourceFile) + ".fl"; o.scDestFile = scAcctPath + wstos(wscDir) + "\\" + wstos(wscDestFile) + ".fl"; o.scDestFileTemp = scAcctPath + wstos(wscDir) + "\\" + wstos(wscSourceFile) + ".fl.renaming"; pendingRenames.push_back(o); HkKickReason(o.wscCharname, L"Updating character, please wait 10 seconds before reconnecting"); IniWrite(scRenameFile, "General", wstos(o.wscNewCharname), itos((int)time(0))); return true; }
void Timer() { // Every 100 seconds expire unused tags and save the tag database /* uint curr_time = (uint)time(0); if (curr_time % 100) { for (std::map<wstring, TAG_DATA>::iterator i = mapTagToPassword.begin(); i != mapTagToPassword.end(); ++i) { if (i->second.last_access < (curr_time - (3600 * 24 * 30))) { mapTagToPassword.erase(i); break; } } SaveSettings(); } */ // Check for pending renames and execute them. We do this on a timer so that the // player is definitely not online when we do the rename. while (pendingRenames.size()) { RENAME o = pendingRenames.front(); if (HkGetClientIdFromCharname(o.wscCharname)!=-1) return; pendingRenames.pop_front(); CAccount *acc = HkGetAccountByCharname(o.wscCharname); // Delete the character from the existing account, create a new character with the // same name in this account and then copy over it with the save character file. try { if (!acc) throw "no acc"; HkLockAccountAccess(acc, true); HkUnlockAccountAccess(acc); // Move the char file to a temporary one. if (!::MoveFileExA(o.scSourceFile.c_str(), o.scDestFileTemp.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) throw "move src to temp failed"; // Decode the char file, update the char name and re-encode it. // Add a space to the value so the ini file line looks like "<key> = <value>" // otherwise Ioncross Server Operator can't decode the file correctly flc_decode(o.scDestFileTemp.c_str(), o.scDestFileTemp.c_str()); IniWriteW(o.scDestFileTemp, "Player", "Name", o.wscNewCharname); if (!set_bDisableCharfileEncryption) { flc_encode(o.scDestFileTemp.c_str(), o.scDestFileTemp.c_str()); } // Create and delete the character HkDeleteCharacter(acc, o.wscCharname); HkNewCharacter(acc, o.wscNewCharname); // Move files around if (!::MoveFileExA(o.scDestFileTemp.c_str(), o.scDestFile.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) throw "move failed"; if (::PathFileExistsA(o.scSourceFile.c_str())) throw "src still exists"; if (!::PathFileExistsA(o.scDestFile.c_str())) throw "dest does not exist"; // The rename worked. Log it and save the rename time. AddLog("NOTICE: User rename %s to %s (%s)",wstos(o.wscCharname).c_str(),wstos(o.wscNewCharname).c_str(), wstos(HkGetAccountID(acc)).c_str()); } catch (char *err) { AddLog("ERROR: User rename failed (%s) from %s to %s (%s)", err, wstos(o.wscCharname).c_str(),wstos(o.wscNewCharname).c_str(), wstos(HkGetAccountID(acc)).c_str()); } } while (pendingMoves.size()) { MOVE o = pendingMoves.front(); if (HkGetClientIdFromCharname(o.wscDestinationCharname)!=-1) return; if (HkGetClientIdFromCharname(o.wscMovingCharname)!=-1) return; pendingMoves.pop_front(); CAccount *acc = HkGetAccountByCharname(o.wscDestinationCharname); CAccount *oldAcc = HkGetAccountByCharname(o.wscMovingCharname); // Delete the character from the existing account, create a new character with the // same name in this account and then copy over it with the save character file. try { HkLockAccountAccess(acc, true); HkUnlockAccountAccess(acc); HkLockAccountAccess(oldAcc, true); HkUnlockAccountAccess(oldAcc); // Move the char file to a temporary one. if (!::MoveFileExA(o.scSourceFile.c_str(), o.scDestFileTemp.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) throw "move src to temp failed"; // Create and delete the character HkDeleteCharacter(oldAcc, o.wscMovingCharname); HkNewCharacter(acc, o.wscMovingCharname); // Move files around if (!::MoveFileExA(o.scDestFileTemp.c_str(), o.scDestFile.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) throw "move failed"; if (::PathFileExistsA(o.scSourceFile.c_str())) throw "src still exists"; if (!::PathFileExistsA(o.scDestFile.c_str())) throw "dest does not exist"; // The move worked. Log it. AddLog("NOTICE: Character %s moved from %s to %s", wstos(o.wscMovingCharname).c_str(), wstos(HkGetAccountID(oldAcc)).c_str(), wstos(HkGetAccountID(acc)).c_str()); } catch (char *err) { AddLog("ERROR: Character %s move failed (%s) from %s to %s", wstos(o.wscMovingCharname).c_str(), err, wstos(HkGetAccountID(oldAcc)).c_str(), wstos(HkGetAccountID(acc)).c_str()); } } }