Game Development Community

Almost functional account management?

by Dreamer · in Torque Game Engine · 03/16/2005 (7:03 am) · 14 replies

For my game I came up with a great little set of scripts to allow you to authenticate a user, and if needs be allow them to create a new account.

I works great, only problem is even though I have the proper code in all the right places i.e. Client stuff is under client and server stuff is under server, the client authenticates itself, rather than asking the server to do it.

I'm not exactly sure what's causing it, except that maybe the client is unaware of the server on the lan, so if someone could show me what to modify to query the lan for a server, then try to authenticate with the server on my lan, it would be much appreciated.

My scripts below assume that you have followed one of the various SQLite integration tools.

I am breaking this up to get it to fit withing the 4096 character per post limit.

#1
03/16/2005 (7:03 am)
Add the following file under starter.fps/client/gui/AccountGUI.gui
$AccountName = "";
$AccountPassword = "";
new GuiControl(AccountGUI) {
   profile = "GuiDefaultProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "320 240";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";

   new GuiWindowCtrl() {
      profile = "GuiWindowProfile";
      horizSizing = "center";
      vertSizing = "center";
      position = "131 10";
      extent = "377 303";
      minExtent = "8 8";
      visible = "1";
      helpTag = "0";
      text ="Account Info";
      maxLength = "255";
      resizeWidth = "0";
      resizeHeight = "0";
      canMove = "1";
      canClose = "1";
      canMinimize = "0";
      canMaximize = "0";
      minSize = "25 25";
      closeCommand = "Canvas.popDialog(AccountGUI);";
   new GuiTextCtrl() {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "36 30";
         extent = "63 18";
         minExtent = "8 8";
         visible = "1";
         text = "User Name:";
         maxLength = "255";
            helpTag = "0";
      };
   new GuiTextEditCtrl() {
         profile = "GuiTextEditProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "36 50";
         extent = "134 18";
         minExtent = "8 8";
         visible = "1";
        //variable = "pref::Player::Name";
	 variable = "$AccountName";
         maxLength = "255";
         historySize = "0";
         password = "0";
         tabComplete = "0";
         sinkAllKeyEvents = "0";
            helpTag = "0";
      };
   
   new GuiTextCtrl() {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "36 70";
         extent = "63 18";
         minExtent = "8 8";
         visible = "1";
         text = "Password:";
         maxLength = "255";
            helpTag = "0";
      };         
   new GuiTextEditCtrl() {
         profile = "GuiTextEditProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "36 90";
         extent = "134 18";
         minExtent = "8 8";
         visible = "1";
        //variable = "pref::Player::Password";
	 variable = "$AccountPassword";
         maxLength = "255";
         historySize = "0";
         password = "1";
         tabComplete = "0";
         sinkAllKeyEvents = "0";
            helpTag = "0";
   };
   new GuiButtonCtrl() {
      profile = "GuiButtonProfile";
      horizSizing = "right";
      vertSizing = "top";
      position = "36 110";
      extent = "134 18";
      minExtent = "8 8";
      visible = "1";
      command = "LoginAccount($AccountName, $AccountPassword);";
      text = "Login to Existing Account";
      groupNum = "-1";
      buttonType = "PushButton";
         helpTag = "0";
   };
   new GuiButtonCtrl() {
      profile = "GuiButtonProfile";
      horizSizing = "right";
      vertSizing = "top";
      position = "36 130";
      extent = "134 18";
      minExtent = "8 8";
      visible = "1";
      command = "CreateAccount($AccountName,$AccountPassword);";
      text = "Create New Account";
      groupNum = "-1";
      buttonType = "PushButton";
         helpTag = "0";
   };
  };
  };
#2
03/16/2005 (7:04 am)
Function LoginAccount($AccountName,$AccountPassword){
  	echo($AccountName @" Is attempting to login, using password " @ $AccountPassword);
	if($AccountName !$="" && $AccountPassword !$= ""){
		if(serverValidateAccount($AccountName,$AccountPassword)){
			Canvas.PopDialog(AccountGUI);
			Canvas.setContent(JoinServerGUI);
		}else{
			MessageBoxYesNo( "Login Information Incorrect!","Do you wish to create a new account?","CreateAccount($AccountName,$AccountPassword);", "");
		}
			
	}else{
		MessageBoxOK("Error!","Your User Name and/or Password are empty");
	}		
}

function CreateAccount($AccountName,$AccountPassword){
	if($AccountName !$="" && $AccountPassword !$= ""){
		echo("Attempting to create " @ $AccountName @", using password " @ $AccountPassword);
		serverCreateAccount($AccountName,$AccountPassword);
		LoginAccount($AccountName,$AccountPassword);
	}else{
		MessageBoxOK("Error!","Your User Name and/or Password are empty");
	}
}
#3
03/16/2005 (7:09 am)
Next create a button in your mainmenugui.gui
new GuiButtonCtrl() {
      profile = "GuiButtonProfile";
      horizSizing = "right";
      vertSizing = "top";
      position = "36 110";
      extent = "134 18";
      minExtent = "8 8";
      visible = "1";
      command = "Canvas.PushDialog(AccountGUI);";
      text = "Login to Existing Account";
      groupNum = "-1";
      buttonType = "PushButton";
         helpTag = "0";
   };

Then add
exec("./ui/AccountGUI.gui");
To your client/init.cs

Finally open server/scripts/commands.cs and add the following
$dbname = "mydb";

//SQLite Functions
function serverValidateAccount(%AccountName,%AccountPassword){
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   
   // open database
   if (sqlite.openDatabase($dbname) == 0)
   {
      echo("ERROR: Failed to open database: " @ $dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   %query = "CREATE TABLE Accounts (Name VARCHAR(20),password VARCHAR(20))";
   %result = sqlite.query(%query, 0);
   if (%result == 0)
   {
      // query failed
      echo("Table already exists table creation aborted.");
      //sqlite.closeDatabase();
      //sqlite.delete();
      //return;
   }
   %query ="SELECT * FROM Accounts WHERE Name = \'" @ %AccountName @ "\' AND Password = \'" @ %AccountPassword @ "\'";
   echo(%query);
   %result = sqlite.query(%query,0);
   if (sqlite.numRows(%result) > 0){
   	echo("If we are seeing this then the server has found a match for the Account name and Password");
   	sqlite.clearResult(%result);
   	sqlite.closeDatabase();
   	return(true);
   }else{
   	echo("If we are seeing this then the server was unable to find a match for the Account name and Password");
	sqlite.clearResult(%result);
   	sqlite.closeDatabase();
   	return(false);
   }
}

function serverCreateAccount(%AccountName,%AccountPassword){
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   
   // open database
   if (sqlite.openDatabase($dbname) == 0)
   {
      echo("ERROR: Failed to open database: " @ $dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   %query ="INSERT INTO Accounts (Name,Password) VALUES (\'" @ %AccountName @ "\',\'" @ %AccountPassword @ "\')";
   echo(%query);
   %result = sqlite.query(%query,0);
   if(%result){
   	echo("If we are seeing this then the server was able to insert the Account name and Password");
   	sqlite.clearResult(%result);
   	sqlite.closeDatabase();
   	return(true);
   }else{
   	echo("If we are seeing this then the server was not able to insert the Account name and Password");
	sqlite.clearResult(%result);
   	sqlite.closeDatabase();
   	return(false);
   }
}

That should be everything.
It works great in single player mode, and I'm not sure why but it doesn't seem to authenticate against the server even if I'm running the server in a seperate session on the localhost.

Any ideas?
#4
03/16/2005 (7:25 am)
The problem, at a quick before hot choclate glance, is that you aren't actually communicating with the server. Just placing code in the server directory means absolutely nothing(Well not really NOTHING but i'm keeping it simple for clarification :p). What you need to be doing is using commandToServer and commandToClient.

I don't have the time right now to go and rewrite your code completely, but here is a small piece to show what I mean.

function CreateAccount($AccountName,$AccountPassword){
   if($AccountName !$="" && $AccountPassword !$= ""){
      echo("Attempting to create " @ $AccountName @", using password " @ $AccountPass
word);
      serverCreateAccount($AccountName,$AccountPassword);
      LoginAccount($AccountName,$AccountPassword);
   }else{
      MessageBoxOK("Error!","Your User Name and/or Password are empty");
   }
}

In the above code you are making a simple function call to serverCreateAccount. That however does not do anythign with the server, it just calls the function with that name locally. Placing the functio in the server commands.cs does nothing to make it server side, and calling the function with the prefix server doesn't either :)

Change that function call to look like this:

[/code]
function CreateAccount($AccountName,$AccountPassword){
if($AccountName !$="" && $AccountPassword !$= ""){
echo("Attempting to create " @ $AccountName @", using password " @ $AccountPass
word);
commandToServer('CreateAccount', $AccountName, $AccountPassword);
LoginAccount($AccountName,$AccountPassword);
}else{
MessageBoxOK("Error!","Your User Name and/or Password are empty");
}
}[/code]

That will send a message to the server telling it to run a function called 'serverCmdCreateAccount', and pass in the params specified to that function on the server.

function serverCmdCreateAccount(%client, %AccountName,%AccountPassword){
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   
   // open database
   if (sqlite.openDatabase($dbname) == 0)
   {
      echo("ERROR: Failed to open database: " @ $dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest a
borted.");
      sqlite.delete();
      return;
   }
   %query ="INSERT INTO Accounts (Name,Password) VALUES (\'" @ %AccountName @ "\',\'"
 @ %AccountPassword @ "\')";
   echo(%query);
   %result = sqlite.query(%query,0);
   if(%result){
      echo("If we are seeing this then the server was able to insert the Account name
 and Password");
      sqlite.clearResult(%result);
      sqlite.closeDatabase();
      return(true);
   }else{
      echo("If we are seeing this then the server was not able to insert the Account 
name and Password");
   sqlite.clearResult(%result);
      sqlite.closeDatabase();
      return(false);
   }
}

That is rewroked slightly to make it exectued by the commandToServer. Note the function name is prefixed with serverCmd and note that I added as the first param a %client var. This is automitcly filled in with the client's id that requsted the function.

For more information on messaging I highly recommend you read this part of the torqe docs:
*I'll edit this post in a minute once I find the link*
#5
03/16/2005 (7:30 am)
Ahh ok I think I see where I'm going wrong with this.
So how does the return work? How do I give the client a success or failure message?
#6
03/16/2005 (7:31 am)
With commandToClient.

Here is the link I needed to search for:
http://www.garagegames.com/docs/torque/general/ch07s11.php

At the bottom of that page is a small bit about commandToServer and commandToClient.
#7
03/16/2005 (7:34 am)
Kewl, I'll fix this right up and make it a resource. Thanx!
#8
08/09/2005 (7:18 pm)
Hi Dreamer,

i am actually a student currently creating a mutiplayer game for my school project. for my game i also need login system. i think what u did for .cs and .gui i can understand . but i am not good in C++ code and dont know how to link torque to SQL(i am using window not linux and my school only support SQL database). can u please share with me your C++ code or do u have resourses similar with what i want(link torque to SQL only (NOT MYSQL))? thanks :)
#9
08/09/2005 (7:47 pm)
Actually this thread is quite a bit dated, you best bet for what you are talking about would either be to follow the ODBC for Torque tutorial which should connect you to an MSSQL DB, or to compile the database engine directly into the the Torque Game Engine which is what I did in my MMORPG series of tutorials, as well as the MMORPG Advanced tutorial

Being that you are in a windows only environment, I believe simply following John Vanderbecks, SQLite for Torque tutorial would be the best place to start since it requires only a bare minimum of knowledge to implement.
#10
08/10/2005 (2:29 am)
Hi dreamer,

i have looked through John Vanderbecks tutorial on SQLite. i decided to give it a try by using ur scripts to combine with John Vanderbecks files, they are sqlite.h, sqlite.lib, SQLiteObject.cc, SQLiteobject.h and Sqlite.dll. however, in your scrpit for server/scripts/commands.cs , there is a line

$dbname = "mydb";

think this will be the most important sentence for me to link to my own database from torque. "mydb" should be ur database name. let say my own database named "ABC", can i just replace with yours? Or do i need to edit some parts of the files given by John Vanderbecks inorder to combine your scripts with his files?
#11
08/10/2005 (2:32 am)
Sorry dreamer i mean replace "mydb" with "ABC" :p
#12
08/10/2005 (8:23 am)
Give it a trry.
#13
08/11/2005 (2:00 am)
Hi dreamer,
i had took john's files and compiled,no problem.
but when i when i compile .cs and .gui , there is error:

Loading compiled script common/server/kickban.cs.
Loading compiled script common/server/game.cs.
Compiling starter.fps/server/scripts/commands.cs...
starter.fps/server/scripts/commands.cs Line: 120 - Syntax error.
>>> Advanced script error report. Line 239.
>>> Some error context, with ## on sides of error halt:
%query ="SELECT * FROM Accounts WHERE Name = \" @ %AccountName @ "\## ##AND Password = \" @ %AccountPassword @ "\";

echo(%query);

%result = sqlite.query(%query,0);
>>> Error report complete.

Loading compiled script starter.fps/server/scripts/commands.cs.
Loading compiled script starter.fps/server/scripts/centerPrint.cs.

can u please tell me what had i did wrong?
#14
08/17/2005 (6:35 pm)
Hi Dreamer,
i still cant solve that problem and i really need help.. so can u please reply if u know what is my mistake.
please reply :)