Beispiel #1
0
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);
}
Beispiel #3
0
/** 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();
		}
}
Beispiel #4
0
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);
}
Beispiel #5
0
	/** 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;
}
Beispiel #7
0
	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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
	/** 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;
	}
Beispiel #13
0
	/** 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;
	}
Beispiel #14
0
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());
}
Beispiel #15
0
	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;
	}
Beispiel #16
0
	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());
			}
		}
	}