Server freezes when a player leaves, can't find out why
#1

Does anybody know why my server would freeze when a player leaves? It would freeze for about 20 seconds, and unfreeze. It's a problem for my server, and I can't find anything in my script that would have something to do with it.

(I've checked OnPlayerConnect & OnPlayerDisconnect, can't find any problems...)
This is really confusing me.
Reply
#2

Are youd oing any IO that might be blocking the servers thread?
Reply
#3

Quote:
Originally Posted by [Bios]Marcel
View Post
Are youd oing any IO that might be blocking the servers thread?
No I'm not, I compiled my server about 2 weeks ago to see if there were any errors before I tried hosting the server. Everything was fine, but when I got in-game and invited friends, once they would leave the server would freeze for 20 seconds, I don't know where this thing could be in my script.
Reply
#4

if it unfreezes after 20 seconds, its probably your save user file script. like if you are using dini or a mysql server outside of your server machine and internet is laggy. and you are trying to save everybody online when somebody leaves. These are all i can think about but give them a try. By checking them.

Also show us your OnPlayerDisconnect
Reply
#5

Code:
public OnPlayerDisconnect(playerid, reason)
{
	(Bank robbery begins here)
	if(BankRobber[playerid])
    {
	    new Rob = BankRobber[playerid]-1, string[128];
	    DisablePlayerCheckpoint(playerid);
		BankRobbersCount --;
		format(BankRobbers[Rob], MAX_PLAYER_NAME, "");
		DeliverMoney[playerid] = 0;

		foreach(Player, i)
		{
		    if(BankRobber[i] || PlayerInfo[i][pFac] == 1)
		    {
				if(Rob == 0) TextDrawHideForPlayer(i, Textdraw1);
				else if(Rob == 1) TextDrawHideForPlayer(i, Textdraw2);
				else if(Rob == 2) TextDrawHideForPlayer(i, Textdraw3);
				else if(Rob == 3) TextDrawHideForPlayer(i, Textdraw4);
				else if(Rob == 4) TextDrawHideForPlayer(i, Textdraw5);
			}
		}
		format(string, sizeof(string), "** %s has disconnected and has failed the robbery. **", RPN(playerid));
		SendRobberyMessage(COLOR_LIGHTRED, string);
		SendCopMessage(COLOR_LIGHTRED, string);
		BankRobber[playerid] = 0;
		if(BankRobbersCount == 0)
		{
			TextDrawHideForAll(Textdraw0);
			TextDrawHideForAll(Textdraw1);
			TextDrawHideForAll(Textdraw2);
			TextDrawHideForAll(Textdraw3);
			TextDrawHideForAll(Textdraw4);
			TextDrawHideForAll(Textdraw5);
			BankRobbery = 0;
			RobberyStarted = 0;
			format(string, sizeof(string), "** The bank robbery has ended, $%d were stolen and $%d were saved. **", TotalStolen*10000, (TotalRobbers*10000-(TotalStolen*10000)));
			SendClientMessageToAll(COLOR_YELLOW, string);
			TotalRobbers = 0;
			new copsonline;
			foreach(Player, i)
			{
			    if(IsACop(i)) copsonline++;
			}
			foreach(Player, i)
			{
			    if(IsACop(i))
			    {
					new Saved = (TotalRobbers*10000-(TotalStolen*10000));
					GiveDodMoney(i, Saved/copsonline);
					format(string, sizeof(string), "** You have received your cut from the saved money. ($%d)", Saved/copsonline);
					SendClientMessage(i, COLOR_LIME, string);
			    }
			}
		}
    }
    RemovePlayerAttachedObject(playerid, 0);

    (This is the paintball part)
    if(PlayerPaintballing[playerid] == 1)
	{
	    ResetPlayerWeapons(playerid);
	    ResetDodWeapons(playerid);
	    SetPlayerPos(playerid,1310.1110,-1368.5656,13.517786);
	    for(new w = 0; w < 13; w++)
		{
		    GiveDodWeapon(playerid, PlayerInfo[playerid][pWeapon][w], PlayerInfo[playerid][pWeaponAmmo][w]);
		}
	}
	(This is the Boxing part)
	new string[128];
	if(Boxing[playerid])
	{
        (Boxing opponents ID)
		new playerb = -1;
        foreach(Player, i)
        {
            if(Boxing[i] && i != playerid) playerb = i;
        }
        if(playerb != -1)
        {
            format(string, sizeof(string), "Boxing Ring: The boxing match has ended, %s has won the match.", RPN(playerb));
    		SendGymMessage(COLOR_WHITE, string);
            (This puts them out of the boxing ring)
            SetPlayerPos(playerb, 760.9759,4.7187,1000.7084);
            SetPlayerFacingAngle(playerb, 268.9407);
            SetPlayerPos(playerid, 760.9759,6.1794,1000.7093);
            SetPlayerFacingAngle(playerid, 268.9407);
            (Winner of boxing match will win the bet amount)
            new oldj = strval(RPJL(playerb, JOB_BOXER));
            PlayerInfo[playerb][pJobSkill][JOB_BOXER] ++;
			new newj = strval(RPJL(playerb, JOB_BOXER));
		    if(oldj < newj)
			{
			    format(string, sizeof(string), "** Your Boxer level is now %d, you can now cause %d more damage. **", newj, (newj*2)-2);
				SendClientMessage(playerb, COLOR_YELLOW, string);
			}
			//
			SendClientMessage(playerb, COLOR_LIME, " You have won the boxing match.");
			SendClientMessage(playerid, COLOR_LIGHTRED, " You have lost the boxing match.");
			(This is where placing bids are)
			new winner = pBoxer[playerb];
			foreach(Player, i)
			{
			    if(BidBoxer[i] == winner)
			    {
			        new percent, profit;
			        percent = (BidAmount[i]/BoxerBid[winner]) * 100;
			        profit = (percent * BoxerBid[pBoxer[playerid]]) / 100;
			        GiveDodMoney(i, BidAmount[i] + profit);
			        format(string, sizeof(string), " You have won $%d from bidding in the match, the money you bid has been returned as well.", profit);
			        SendClientMessage(i, COLOR_LIME, string);
			    }
				BidAmount[i] = 0;
				BidBoxer[i] = 0;
			}
			for(new w = 0; w < 13; w++)
			{
			    GiveDodWeapon(playerb, PlayerInfo[playerb][pWeapon][w], PlayerInfo[playerb][pWeaponAmmo][w]);
			}
        }
        for(new w = 0; w < 13; w++)
		{
		    GiveDodWeapon(playerid, PlayerInfo[playerid][pWeapon][w], PlayerInfo[playerid][pWeaponAmmo][w]);
		}
        
		BoxingMatch = 0;
		Boxer[1] = -1;
		pBoxer[playerb] = 0;
		Boxer[2] = -1;
		pBoxer[playerid] = 0;
		Boxing[playerb] = 0;
		Boxing[playerid] = 0;
		BoxerBid[1] = 0;
		BoxerBid[2] = 0;
	    if(BoxTime)
	    {
			TogglePlayerControllable(playerb, 1);
	    	KillTimer(BoxTimer);
	    }
    }
	
	if(IsPlayerLoggedIn(playerid)) {SaveChar(playerid);}
	switch(reason)
	{
	    case 0: format(string, sizeof(string), "* %s has left the server. (Timeout)", RPN(playerid));
	    case 1: format(string, sizeof(string), "* %s has left the server. (Leaving)", RPN(playerid));
	    case 2: format(string, sizeof(string), "* %s has left the server. (Kicked/Banned)", RPN(playerid));
	}
	SendNearbyMessage(playerid, 10, string, COLOR_YELLOW, COLOR_YELLOW, COLOR_YELLOW, COLOR_YELLOW, COLOR_YELLOW);
	foreach(Player, i)
	{
	    if(Specid[i] == playerid)
	    {
	        Spec[i] = 0;
			Specid[i] = -1;
	    	TogglePlayerSpectating(i, 0);
			SetPlayerVirtualWorld(i, PlayerInfo[playerid][pVW]);
			SetPlayerInterior(i, PlayerInfo[playerid][pInt]);
			SetPlayerPos(i, PlayerInfo[playerid][pX], PlayerInfo[playerid][pY], PlayerInfo[playerid][pZ]);
			SendClientMessage(i, COLOR_WHITE, " You have stopped spectating players.");
	    }
	}
	(This is where the clearing AD begins)
	for(new i=0; i<MAX_ADS; i++)
	{
		if(strfind(AD[i], RPN(playerid)) != -1)
   		{
   		    format(AD[i], 128, "");
   		}
   	}
        (This is where AD clearing ends)
	ClearChar(playerid);
	if(Planted[playerid] == 1)
	{
	    DestroyObject(C4[playerid]);
	    Bomb[playerid] = 0;
	    Planted[playerid] = 0;
	}
	return 1;
}
That is my whole OnPlayerDisconnect code, I added in some things to let you know what is what in it. I can't seem to find anything wrong with it, can you?
Reply
#6

Try to remove some parts of code and you will see which part is lagging or add printfs with gettime and you will see where time is big
Reply
#7

okay so lets do it step by step? ok so before freezing happens, you have many SendClientMessages. After which one freeze happens? you should be able to track it which will give us the exact reason of freeze. You have so many on player disconnect.
Reply
#8

Quote:
Originally Posted by grymtn
View Post
okay so lets do it step by step? ok so before freezing happens, you have many SendClientMessages. After which one freeze happens? you should be able to track it which will give us the exact reason of freeze. You have so many on player disconnect.
Not too sure on how to track it, could you explain how I could? Never tried to track before =/
Reply
#9

like login to your character with 2 pcs and just register to every action you can thats in your onplayerdisconnect. then get close on second acc to your first acc and logout from first acc. it should try to send every client messages in there. so you can know which one it get stucks on then write it on here. use a tp command to register every action
Reply
#10

Quote:
Originally Posted by grymtn
View Post
like login to your character with 2 pcs and just register to every action you can thats in your onplayerdisconnect. then get close on second acc to your first acc and logout from first acc. it should try to send every client messages in there. so you can know which one it get stucks on then write it on here. use a tp command to register every action
I don't have two pc's, so ... I really don't know what to do at this point.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)