Page 1 of 1

login issue

Posted: 18 Jul 2011, 08:11
by steanson
Hi wondering if you could help with an issue we are having
When i login a user i get this message but not all the time:

[ WARNING ] > Room list was requested by a non logged user!

I'm wondering what could be causing this.
Should I put the forceLogin flag to true in the canLogin method?

here is the code i'm using for the login check

Code: Select all

private void loginCheck(String nameKey, SocketChannel chan)
	{
		// convert nameKey to userID by reading key from database
		
		boolean ok = true;
		
		// Prepare a response object for the client
		JSONObject res = new JSONObject();
		
		//check if user is still playing a tournament
		
		-- if user is still in a tournament set ok to false
		
		if (ok)
		{
			try
			{
				User usr = null;
				try{
					usr = zone.getUserByName(nameID);
					if(usr !=null)
					{
						xtHelper.logoutUser(usr, false);
					}else{
						//trace("not logged in");
					}
				}catch(Error e){ log("error getting  user "+ nameID); }
				
				// Attempt to login the user in the system
				
				usr = xtHelper.canLogin(nameID, "", chan, ZONE_NAME, true);
								
				
				if(usr != null )
				{
					res.put("cmd", CMD_LOG_OK);
				}else{
					//trace("setting ok to false");
					ok = false;
				}
			}
			// An exception occurred while logging the user in
			catch (Exception le)
			{
				log("Could not login user: " + nameID);
				try{
					res.put("cmd", CMD_LOG_FAIL);
					res.put("msg", le.getMessage());
				}catch(Exception e){ trace("Failed to create response " + e.toString());}
			}	
		}
		
		// The user name is not among the valid ones
		else
		{
			try
			{
				res.put("cmd", CMD_LOG_FAIL);
				if(nameID == null) 
				{
					res.put("msg", "User access error");
				}else{ 
					res.put("msg", "Already playing");
				}
			}catch(Exception e){log("ERROR - Failed to create response 2 "+ e.toString());}
		}
		
		// Prepare the list of recipients, in this case we only one.
		LinkedList<SocketChannel> ll = new LinkedList<SocketChannel>();
		ll.add(chan);

		// Send login response
		sendResponse(res, -1, null, ll);	

		// Send room list
		if (ok)
			xtHelper.sendRoomList(chan);
	}

Posted: 18 Jul 2011, 10:33
by Sarevok
First of all, your method is doing far too much. You should break it into more smaller ones, because it is pain to read through it :)

What happens if xtHelper.canLogin throws an exception? In catch block you don't set "ok" value to false, and later you have:

Code: Select all

if (ok)
         xtHelper.sendRoomList(chan);
And ok is true even if login was not successful (exception thrown by canLogin).

It is possible, that there is more similar bugs, but it is hard to spot them in very long method :)

Also, can you post all traces on server in cases when you get that warning?

Posted: 18 Jul 2011, 10:55
by steanson
Fair comment on the length of this method - thankyou

typically i get this in the logs:

User: 602 is already logged in Zone: fb
Old user object found
Old User ID: 1002
Old User IP: ****
[UsersById] query: it.gotoandplay.smartfoxserver.data.User@19fea29
[Clients] query: true
[UsersByChannel] query: null
[ChannelQueues] query: []

User was found in 0 room(s) ::

[ INFO ] > Could not login user: 602
[ WARNING ] > Room list was requested by a non logged user! IP: *****

"please not that 602 is the username"
thanks Steve

Posted: 18 Jul 2011, 12:40
by Sarevok
This is javadoc for canLogin method:
Checks if a connected client can log in the requested Zone.
If the Zone is full, or a user with the same name already exist a LoginException will be thrown.
Before logging in a Zone a client has a very limited set of actions that can perform with the server.
Once the login phase is successfully passed, a User object is created and added to the Zone allowing the user to interact with the server.
Bolded part is crucial here. This is what happens in your case (at least I think so):

Your client application doesn't close connection to server (it is not rare situation, especially if your client is browser-flash application). So as far as server is concerned user is still logged in, and it will take few minutes until he is disconnected (idle timeout). In the meantime you try to log in that user again, and canLogin() method in your code throws an exception. You catch exception, but "ok" variable is not set to false in the catch block. Because of that, at the end of your method you try to send room list to non logged user, and you get warning: room list is requested by non logged user.

Why did you commented trace() calls in your loginCheck() method? It would give us a lot more info about execution path of your code at the time when warning happened? :)

Posted: 18 Jul 2011, 12:53
by steanson
The way our game works; when the user finishes the tournament they are directed out of the game / navigate away from the flash.

So in order to play again they reload the flash in the browser and then go thru the logincheck method

above the canLogin i do this:

User usr = null;
try{
usr = zone.getUserByName(nameID);
if(usr !=null)
{
xtHelper.logoutUser(usr, false);
}else{
//trace("not logged in");
}
}catch(Error e){ log("error getting user "+ nameID); }

would that not effectively remove them so i can log them back into the room?
this doesn't seem to work so how else do i get them back in the Room ?

thanks once again Steve
thanks Steve

Posted: 18 Jul 2011, 13:07
by Sarevok
Problem is that we don't know why exactly it goes wrong, because we have too few information. You should put trace() all over your method (just for debugging) to check exact execution path of method when it generates warning. That way you will know if user is actually logged out, and so on.

Please, put traces in every possible execution path and when warning happens, copy here entire trace log.

Another option is to turn on remote debugging, you have tutorial among sticky threads.

I want to mention again: even if you manage to logout user before canLogin(), your method still have a bug, because server can be full, and canLogin will throw exception for that reason, so you will get same warning again :)

Posted: 18 Jul 2011, 13:29
by steanson
I need to do add the traces later when there a fewer users on.
And will post back as soon as possible
I did spot the force login flag in the canLogin method, would that address the issue?


thanks Steve

Posted: 18 Jul 2011, 13:59
by Sarevok
Yes, force login should solve issue of user not being able to log in due to non-closed connection. But I am not sure it is the main problem you have. That way you could probably hide the problem, but it wouldn't be solved, and when bug happens it would be even harder to find :)

Posted: 18 Jul 2011, 14:18
by steanson
currently i don't use the forceLogin at all, I will add that apply traces to the various branches of logic and let you know
thanks once again

Steve