Hi Lapo, you are correct, getting the user in disconnect is better, but still I have the same issue where I need to store the username or account_id inside the user upon login, I currently try to store it in the LoginPostProcess in the loginData.session, but for some reason my LoginPostprocess execute function isnt getting called anymore either...
heres my code:
C# Client:
Code: Select all
public static class SFS_Login
{
static string CMD_SUBMIT = "$Login.Submit";
public static void RegisterListeners()
{
// Add listeners to SFS Client Instance
Debug.Log("registering SFS_Login Listeners");
SFS.Client.RemoveEventListener(SFSEvent.EXTENSION_RESPONSE, onLoginResponse);
SFS.Client.AddEventListener(SFSEvent.EXTENSION_RESPONSE, onLoginResponse);
}
public static void SendLoginData(string username, string pass)
{
// this gets called when I login
Debug.Log("Login user: " + username + ", plain pass: " + pass);
string md5Pass = PasswordUtil.MD5Password(pass);
SFS.Client.Send(new Sfs2X.Requests.LoginRequest(username,
md5Pass,
SFS.Client.Config.Zone));
}
static void onLoginResponse(BaseEvent evt)
{
// This also never gets called for some reason
string cmd = (string)evt.Params["cmd"];
Debug.Log("Received loginResponse: " + cmd);
SFSObject sfso = (SFSObject)evt.Params["params"];
if (cmd == CMD_SUBMIT)
{
if (sfso.GetBool("success"))
{
Debug.Log("Success, thanks for logging in.");
}
else
Debug.Log("Login error:" + (string)evt.Params["errorMessage"]);
}
}
}
The weird thing is, it was working before... But now responses are not getting triggered on client side and LoginAssistant Post/Preprocess are not getting triggered on server side.
Code: Select all
public class ZoneExtension extends SFSExtension {
ISFSApi API;
DBManager _dbManager;
Login _login;
@Override
public void init() {
API = getApi();
trace("ZoneExtension -- started");
_dbManager = new DBManager();
_dbManager.Init(getParentZone().getDBManager(), this);
trace("DBManager -- started");
_login = new Login();
_login.Init(this); // Login Assistant
trace("Login Assistant -- started");
addEventHandler(SFSEventType.USER_JOIN_ZONE, UserJoinZoneEventHandler.class);
addEventHandler(SFSEventType.USER_DISCONNECT, UserDisconnectEventHandler.class);
addRequestHandler("Characters", RequestCharactersHandler.class);
addRequestHandler("CreateCharacter", RequestCreateCharacterHandler.class);
addRequestHandler("SelectCharacter", RequestSelectCharacterHandler.class);
addRequestHandler("DeleteCharacter", RequestDeleteCharacterHandler.class);
addRequestHandler("MigrateServer", RequestMigrateServerHandler.class);
}
@Override
public void destroy() {
super.destroy();
_login.LAC.destroy();
trace("ZoneExtension -- stopped");
}
}
My LoginAssistant:
Code: Select all
package login;
import java.util.Arrays;
import com.smartfoxserver.v2.components.login.LoginAssistantComponent;
import com.smartfoxserver.v2.extensions.ISFSExtension;
import zone.ZoneExtension;
public class Login {
public LoginAssistantComponent LAC;
String sqlSelect = "SELECT * FROM main.accounts WHERE username=?";
Object[] sqlParams;
ZoneExtension ext;
public void Init(ISFSExtension ext) {
this.ext = (ZoneExtension) ext;
LAC = new LoginAssistantComponent(ext);
// Configure the component
LAC.getConfig().loginTable = "main.accounts";
LAC.getConfig().userNameField = "username";
LAC.getConfig().passwordField = "hash";
LAC.getConfig().useCaseSensitiveNameChecks = true;
LAC.getConfig().extraFields = Arrays.asList("id", "activated", "banned");
// LAC.getConfig().customPasswordCheck = true;
LAC.getConfig().preProcessPlugin = new LoginPreProcessHandler();
LAC.getConfig().postProcessPlugin = new LoginPostProcessHandler(); // This function doesnt get called for some reason?
}
}
PostProcess:
Code: Select all
public class LoginPostProcessHandler implements ILoginAssistantPlugin {
@Override
public void execute(LoginData ld) throws SFSLoginException {
DBManager.Login(ld.userName); // See next code block
ld.session.setProperty("$permission", DefaultPermissionProfile.STANDARD);
ld.session.setProperty("username", ld.userName); // Set username inside session
}
}
How I know PostProcess isnt being called:
Code: Select all
public static void Login(String username) {
try {
_sqlParams = new Object[2];
_sqlParams[0] = "T";
_sqlParams[1] = username;
_dbManager.executeUpdate(_sqlUpdateAccountOnline, _sqlParams);
ext.trace("DB Logged in user: " + username); // This trace never appears in Terminal?
// Thats why i think LoginPostProcess isnt being called at all for some reason?
} catch (SQLException e) {
e.printStackTrace();
}
}
When I try to retrieve the username in another script a few frames after login I get "username : nullReferenceException":
Code: Select all
public static void GetCharacters(User user) {
try {
_sqlParams = new Object[1];
_sqlParams[0] = user.getSession().getProperty("username"); // username = null? why? I stored the username in session in postProcess
ext.trace("username: " + _sqlParams[0]); // this traces as username: null
// Get accountID by username and store in User
ISFSArray accountIDArray = _dbManager.executeQuery(_sqlSelectAccountID, _sqlParams);
int accountID = accountIDArray.getSFSObject(0).getInt("id"); // this gives an index out of bounds because the username was null
user.setProperty("account_id", accountID);
// Get all characters by accountID
_sqlParams[0] = accountID;
ISFSArray dbCharacters = _dbManager.executeQuery(_sqlSelectCharacters, _sqlParams);
if (dbCharacters.size() == 0) {
ext.SendNoCharacters(user);
return;
}
// Parse the DBCharacters to get correct types
ISFSArray parsedCharacters = ParseCharacters(dbCharacters);
parsedCharacters = ISFSExtensions.SortSFSOsByComparator(parsedCharacters, "id");
SFSObject parsedCharactersSFSO = new SFSObject();
parsedCharactersSFSO.putSFSArray("Characters", parsedCharacters);
ext.SendCharacters(user, parsedCharactersSFSO);
} catch (SQLException e) {
e.printStackTrace();
}
}
Any idea what is going on here?
TL:DR:
1.PostProcessLogin => store username in session (Doesnt seem to happen at all because my traces dont get called and dont appear in terminal)
2. retrieve username from session a few frames later => its gone/null
Terminal Traces:
Code: Select all
21:50:57,750 INFO [SocketReader] sessions.DefaultSessionManager - Session removed: { Id: 42, Type: DEFAULT, Logged: Yes, IP: 127.0.0.1:51589 }
21:50:57,750 INFO [SFSWorker:Sys:1] api.SFSApi - User disconnected: { Zone: GuestZone }, ( User Name: Guest#37, Id: 37, Priv: 0, Sess: 127.0.0.1:51589 ) , SessionLen: 27, Type: Unity
------------------------------------------------------------------
----- I added these 3 lines to make it more readable --------
------------------------------------------------------------------
21:51:05,772 INFO [SocketReader] sessions.DefaultSessionManager - Session created: { Id: 43, Type: DEFAULT, Logged: No, IP: 127.0.0.1:51592 } on Server port: 9933 <---> 51592
21:51:05,794 INFO [SFSWorker:Ext:1] api.SFSApi - User login: { Zone: ASOZone0 }, ( User Name: qwerty, Id: 38, Priv: 1, Sess: 127.0.0.1:51592 ) , Type: Unity
21:51:05,796 INFO [SFSWorker:Ext:1] api.SFSApi - Room joined: [ Room: CharacterSelection, Id: 0, Group: default, isGame: false ], { Zone: ASOZone0 }, ( User Name: qwerty, Id: 38, Priv: 1, Sess: 127.0.0.1:51592 ) , asSpect: false
21:51:05,822 INFO [SFSWorker:Ext:2] Extensions - {ZoneExtension}: Received client request: RequestCharacters
21:51:05,823 INFO [SFSWorker:Ext:2] Extensions - {ZoneExtension}: username: null
As you can see :
1. Session Created
2. User Login
3. LoginPosProcess isnt being called
4. Room Joined
5. Username is null when trying to retrieve it from session
For what reason could the server skip PostProcessPlugin? Or is something else going on?
Im using latest sfs2x server 2.19.3
And latest C# API 1.8.3
Thanks.
SFS2X Server Extension settings: