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; }
/** 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 HkLockAccountAccess(CAccount *acc, bool bKick) { char szJMP[] = { '\xEB' }; char szJBE[] = { '\x76' }; flstr *flStr = CreateWString(HkGetAccountID(acc).c_str()); if(!bKick) WriteProcMem((void*)0x06D52A6A, &szJMP, 1); Players.LockAccountAccess(*flStr); // also kicks player on this account if(!bKick) WriteProcMem((void*)0x06D52A6A, &szJBE, 1); FreeWString(flStr); }
/** 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 HkAddConnectLog(uint iClientID, wstring wscReason, ...) { wchar_t wszBuf[1024*8] = L""; va_list marker; va_start(marker, wscReason); _vsnwprintf(wszBuf, (sizeof(wszBuf) / 2) - 1, wscReason.c_str(), marker); FILE *f = fopen(("./flhook_logs/flhook_connects.log"), "at"); if(!f) return false; const wchar_t *wszCharname = (wchar_t*)Players.GetActiveCharacterName(iClientID); if(!wszCharname) wszCharname = L""; CAccount *acc = Players.FindAccountFromClientID(iClientID); wstring wscAccountDir; HkGetAccountDirName(acc, wscAccountDir); time_t tNow = time(0); struct tm *stNow = localtime(&tNow); fprintf(f, "%.2d/%.2d/%.4d %.2d:%.2d:%.2d Connect (%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(wszBuf).c_str(), wstos(wszCharname).c_str(), wstos(wscAccountDir).c_str(), wstos(HkGetAccountID(acc)).c_str()); fclose(f); 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()); } } }
void HkUnlockAccountAccess(CAccount *acc) { flstr *flStr = CreateWString(HkGetAccountID(acc).c_str()); Players.UnlockAccountAccess(*flStr); FreeWString(flStr); }