Vegaserver enhancements

A forum for online playing, administration, bugs and feature requests
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

I started to experiment to work with the database .
I had to download MySQLdb to have the http server work with the sql setting .

I have created a base " vegastrike " and the 2 tables .
But i have a python error when i try to register in the web browser :
Python error occurred in POST request.

Traceback (most recent call last):
File "D:\program\experimental\data\cgi-accountserver\httpserver.py", line 114, in do_POST
self.do_request(contents)
File "D:\program\experimental\data\cgi-accountserver\httpserver.py", line 100, in do_request
module.execute(connections[mod], getargs, postargs)
File "D:\program\experimental\data\cgi-accountserver\register_submit.py", line 44, in execute
if not dbconn.check_password(username, password, True):
File "D:\program\experimental\data\cgi-accountserver\db.py", line 328, in check_password
user_id = answer_row[0]+1
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
I don't know if it's a dev's error or if my table is misconfigured .
That seem to be a dev's error here , because of the "NoneType" .
I'm trying to fix ....

Edit :

The error occurs only at the very first use of the table .
user_id = answer_row[0]+1 fails .
But if i remove answer_row[0] at the first time , a new entry is recorded .
When i do user_id = answer_row[0]+1 after that , the new users are recorded in
the table , as shown in that YAML export :
%YAML 1.1
---
# vegastrike.accounts
-
username: "ezee"
modname: ""
csv: ",\"Directory\",\"Name\",\"STATUS\",\"Object_Type\",\"Combat_Role\",\"Textual_Description\",\"Hud_image\",\"Unit_Scale\",\"Cockpit\",\"CockpitX\",\"CockpitY\",\"CockpitZ\",\"Mesh\",\"Shield_Mesh\",\"Rapid_Mesh\",\"BSP_Mesh\",\"Use_BSP\",\"Use_Rapid\",\"NoDamageParticles\",\"Mass\",\"Moment_Of_Ine"
savegame: "Crucible/Cephid_17^13500.000000^Admonisher 1.19999995963e+11 40008370.0871 -1.09999998137e+11 confed\n0 mission data 1\nunit_to_dock_with 10 9.000000 65.000000 116.000000 108.000000 97.000000 110.000000 116.000000 105.000000 115.000000 0.000000 \n0 missions"
logged_in_server: 0
-
username: "Eye~R"
modname: ""
csv: ",\"Directory\",\"Name\",\"STATUS\",\"Object_Type\",\"Combat_Role\",\"Textual_Description\",\"Hud_image\",\"Unit_Scale\",\"Cockpit\",\"CockpitX\",\"CockpitY\",\"CockpitZ\",\"Mesh\",\"Shield_Mesh\",\"Rapid_Mesh\",\"BSP_Mesh\",\"Use_BSP\",\"Use_Rapid\",\"NoDamageParticles\",\"Mass\",\"Moment_Of_Ine"
savegame: "Crucible/Cephid_17^13500.000000^Nicander 1.19999994389e+11 39994460.3041 -1.09999998714e+11 hunter\n0 mission data 1\nunit_to_dock_with 10 9.000000 65.000000 116.000000 108.000000 97.000000 110.000000 116.000000 105.000000 115.000000 0.000000 \n0 missionstr"
logged_in_server: 0
-
username: "darkvixen"
modname: ""
csv: ",\"Directory\",\"Name\",\"STATUS\",\"Object_Type\",\"Combat_Role\",\"Textual_Description\",\"Hud_image\",\"Unit_Scale\",\"Cockpit\",\"CockpitX\",\"CockpitY\",\"CockpitZ\",\"Mesh\",\"Shield_Mesh\",\"Rapid_Mesh\",\"BSP_Mesh\",\"Use_BSP\",\"Use_Rapid\",\"NoDamageParticles\",\"Mass\",\"Moment_Of_Ine"
savegame: "Crucible/Cephid_17^13500.000000^Admonisher 1.19999998592e+11 39993601.2886 -1.10000005773e+11 confed\n0 mission data 1\nunit_to_dock_with 10 9.000000 65.000000 116.000000 108.000000 97.000000 110.000000 116.000000 105.000000 115.000000 0.000000 \n0 missions"
logged_in_server: 0
...
%YAML 1.1
---
# vegastrike.phpbb_users
-
username: "ezee"
user_id: 1
user_password: "5a98add1f309fd5522b11ba6e299dd"
-
username: "Eye~R"
user_id: 2
user_password: "d2f2297d6e829cd3493aa7de4416a1"
-
username: "darkvixen"
user_id: 3
user_password: "ba248c985ace94863880921d8900c5"
...
The problem is that an entry must already exist in the table for the code to execute .
A quick fix is to create the 'user_table': 'phpbb_users', with a default user , an admin is
perhaps a good idea .

I have tried to play with one of the users i created , but VS crash after showing the
splashscreen that follows " Join " in the multiplayer menu .

stderr say :
ng\lowlevel\vsnet_dloadmgr.cpp:74 Enter VsnetDownload::Client::Manager::Manager
networking\netclient_login.cpp:358 enter NetClient::init_acct with http://127.0.0.1:8080/cgi-bin/accountserver.py
\networking\lowlevel\netui.cpp:18 Initializing Winsock
networking\netclient_login.cpp:365 accountserver on socket 078C2E68 done.
networking\netclient_login.cpp:141 enter NetClient::loginAcctLoop
networking\netclient_login.cpp:151 Buffering to send with LOGIN_DATA for moi
\networking\lowlevel\netui.cpp:75 Connecting to 127.0.0.1 on port 8080
e\src\networking\netclient.cpp:223 >>> LOGIN ERROR =( DENIED )= --------------------------------------
networking\netclient_login.cpp:186 End of loginAcct loop

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

mORE INFO ABOUT THE CLIENT CRASHS WHEN USING DATABASE TO STORE USERS ACCOUNTS :

I have cleared my user table , and added manually one user with :
_username=admin
_user_id=0
_password=abcdefg

Then i have launched the server , and vsclient .
I joined the game without problem !

That mean that the problem is at the password level :
it is recorded encrypted in the database , and the decrypt fails in the code .
As i entered a non-crypted password manually , the login was successful .

I don't know if the error is due to python or c++ code .
But i am happy to have the database system working at 99% .
I will try to change the encryption model , and use 'sha' instead of 'md5' :
password_hash_methode = 'md5' #password can use sha or md5 hash metode

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Eye~R
Hunter
Hunter
Posts: 70
Joined: Sun Jan 19, 2014 5:02 am

Re: Vegaserver enhancements

Post by Eye~R »

Heh, Database mode total failure. WIthout what you'd discovered I doubt I would of got as far as I did.

I also trip on the " TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' " error, but I'm unable to pass it, I assume I've done something wrong in the database?

mysql> SHOW TABLES;DESCRIBE user_table;DESCRIBE account_table;SELECT * FROM user_table;SELECT * from account_table;
+----------------------+
| Tables_in_vegastrike |
+----------------------+
| account_table |
| user_table |
+----------------------+
2 rows in set (0.00 sec)

+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| username | varchar(20) | YES | | NULL | |
| user_id | varchar(20) | YES | | NULL | |
| user_password | varchar(50) | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

+------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| username | varchar(20) | YES | | NULL | |
| modname | varchar(20) | YES | | NULL | |
| csv | varchar(280) | YES | | NULL | |
| savegame | varchar(280) | YES | | NULL | |
| logged_in_server | varchar(10) | YES | | NULL | |
+------------------+--------------+------+-----+---------+-------+
6 rows in set (0.01 sec)

+----+----------+---------+----------------------------------+
| id | username | user_id | user_password |
+----+----------+---------+----------------------------------+
| 0 | test | 0 | testing |
| 1 | test1 | 1 | testing |
| 2 | test2 | 2 | f08a0b49255935ef33ffec923eb0d12a |
+----+----------+---------+----------------------------------+
3 rows in set (0.00 sec)

Empty set (0.00 sec)

Re-reading your post, I tried giving it the password pre-hashed, still cannot either connect to server, or fabricate more users from form.
Multiplayer Server Offline. Copy ony testing rig semi-funcitonal.
User Signup Offline.
Server Health Shows old data from last snapshot before the server downed.

If you have any issues you can usually find me in #vegastrike on freenode.
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

Hey !
:wink:

user-id is a int man !
and the names of the tables MUST MATCH the names in settings.py :
'user_table': 'phpbb_users',
'account_table': 'accounts',
In red are the names you must use for your tables . ( i made the same mistake , i remember now :lol: )
But you can also change their names here ( i suggest to keep that names while we debug )
that will work then !
i will post my config later , i'm not on my pc
:D

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Eye~R
Hunter
Hunter
Posts: 70
Joined: Sun Jan 19, 2014 5:02 am

Re: Vegaserver enhancements

Post by Eye~R »

Re-Created the "user" table, works now, for signup and connection... I'd possibly done something simple. Got some errors, tho:
Starting HTTP server on port 8080...
/cgi-bin/register_submit.py
78.46.69.112 - - [22/Apr/2014 20:28:11] "POST /cgi-bin/register_submit.py HTTP/1.1" 200 -
/home/user/db.py:357: Warning: Field 'id' doesn't have a default value
(username, self.modkey, csv, save))
/home/user/db.py:357: Warning: Data truncated for column 'csv' at row 1
(username, self.modkey, csv, save))
I assume this can be solved by assigning a defaul value(possibly NULL(or maybe that's what the problem is)) and the "CSV" field needs to be wider (think I gave it 280)

Scratch that - It allowed me to create one user, which worked. Now it's back to "IntegrityError: (1062, "Duplicate entry '0' for key 'PRIMARY'")"

Testing yeilds only the 1'st generated user works...
Last edited by Eye~R on Wed Apr 23, 2014 6:02 am, edited 1 time in total.
Multiplayer Server Offline. Copy ony testing rig semi-funcitonal.
User Signup Offline.
Server Health Shows old data from last snapshot before the server downed.

If you have any issues you can usually find me in #vegastrike on freenode.
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

your last error indicate that you forgot to set create-user to true in settings.py
If you have set true , there is another reason to fail , let me show you :
def check_password(self, username, password, can_create=False):
username=username.replace(' ','_')
c = self.conn.cursor() #self.dict_cursor
c.execute('SELECT user_id, user_password FROM ' +
self.user_table + ' WHERE username=%s',
(username,) )
result = c.fetchone()
if result and result[0]:
return self.compare_password(result[1], password)
else:
if self.create_user and can_create:<<<------ create_user AND can_create are true
maxquery = self.conn.cursor()
maxquery.execute('SELECT MAX(user_id) FROM ' + self.user_table)
answer_row = maxquery.fetchone()
user_id = answer_row[0]+1
c = self.conn.cursor()
c.execute('INSERT INTO '+self.user_table +
' (username, user_id, user_password) VALUES ' +
' (%s, '+str(int(user_id))+', %s)',
(username, self.hash_password(password)) )
return True
else:
return False
return False throw the error i guess ...

Now i remember i have changed this line during my tests , then revert to original code for another debug session .
Anyway , change (line 314 in db.py ) :
def check_password(self, username, password, can_create=False):
with
def check_password(self, username, password, can_create=True):
That should work now !
( but you probably will have to edit the passwords to make them human readable , for your client login acceptance )
I don't have solved that issue with the database relative code .
Still in my toto list ...
:wink:

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Eye~R
Hunter
Hunter
Posts: 70
Joined: Sun Jan 19, 2014 5:02 am

Re: Vegaserver enhancements

Post by Eye~R »

Reviewed settings:

Code: Select all


mysql_dbconfig = {
        'type':       'mysql',
        'host':       '127.0.0.1', #'Vegarstrike.armed.me.uk'
        'port':       '3306',
        'passwd':     [Redacted],
        'user':       [Redacted],
        'db':         [Redacted],
        'user_table': 'user_table',
        'account_table': 'account_table',
        'create_user':True,
}
It all works good for the 1'st users generation, After previously manually populating it as you earlier suggested... Leads me to think the issue is within how I've crafted the fields, Something defaulting null where it shouldn't maybe, or not defaulting null where it should...

Whilst awaiting response, will try the " def check_password(self, username, password, can_create=True): " you suggest...

The

Code: Select all

/home/user/db.py:357: Warning: Data truncated for column 'csv' at row 1
(username, self.modkey, csv, save)) 
can't be a good thing, must result in borked saves? How big would this need to be to allow for no potential of truncated data?

Code: Select all

/home/username/db.py:357: Warning: Field 'id' doesn't have a default value
(username, self.modkey, csv, save))
I don't recall creating a "id" field(account_table) - must of tho - It's not needed? Only "id" in the DB is:

Code: Select all

+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| id               | int(11)      | NO   | PRI | NULL    |       |
| username         | varchar(20)  | YES  |     | NULL    |       |
| modname          | varchar(20)  | YES  |     | NULL    |       |
| csv              | varchar(560) | YES  |     | NULL    |       |
| savegame         | varchar(280) | YES  |     | NULL    |       |
| logged_in_server | varchar(10)  | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
Okies.. Redone that to:

Code: Select all

+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| username         | varchar(20)  | YES  |     | NULL    |       |
| modname          | varchar(20)  | YES  |     | NULL    |       |
| csv              | varchar(950) | YES  |     | NULL    |       |
| savegame         | varchar(512) | YES  |     | NULL    |       |
| logged_in_server | int(10)      | NO   | PRI | 0       |       |
+------------------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
Made no difference... The "logged_in_server" is also primary key, and defaults 0 (I thought that made sense, the act of logging in changes it to 1, and should mark 0 as logout..) but maybe I'm an idiot... Increasing "csv" to 950 still results in truncated data...

Nope... editing db.py didn't change much... now don't get any population of table, previously got one user....

Code: Select all

IntegrityError: (1062, "Duplicate entry '0' for key 'PRIMARY'")

Seems to be user_id .. I've tried making other fields key, same net effect... AFAIK, it should auto increment this... Hmm, maybe it's because I don't have a 0 yet.. Nope..

Code: Select all

+----------+---------+----------------------------------+
| username | user_id | user_password                    |
+----------+---------+----------------------------------+
| newuser  |       1 | test                             |
| nouser   |       4 | test                             |
| testuser |       5 | c3aa15540eba579cb92746bfb922860b |
+----------+---------+----------------------------------+
The Auto-Increment seems to work, tho, all three users inserted with "0" as value for user_id ... The gap is two attempts to create accnt via .py form I'd imagine...
Multiplayer Server Offline. Copy ony testing rig semi-funcitonal.
User Signup Offline.
Server Health Shows old data from last snapshot before the server downed.

If you have any issues you can usually find me in #vegastrike on freenode.
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

good .
have you tried to login in vs client then ?

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Eye~R
Hunter
Hunter
Posts: 70
Joined: Sun Jan 19, 2014 5:02 am

Re: Vegaserver enhancements

Post by Eye~R »

Login via VS client fails, Yesterday it'd at least allow login from the "real" user it'd generated, will undo the db.py edit....
Multiplayer Server Offline. Copy ony testing rig semi-funcitonal.
User Signup Offline.
Server Health Shows old data from last snapshot before the server downed.

If you have any issues you can usually find me in #vegastrike on freenode.
Eye~R
Hunter
Hunter
Posts: 70
Joined: Sun Jan 19, 2014 5:02 am

Re: Vegaserver enhancements

Post by Eye~R »

Success!

Props to Glebihan over at LinuxMint.... He quite rightly pointed out with the user_id field on auto-increment there's rightly no need to pass it a value at all, and that's been removed, also added plenty of self.conn.commit() around every interaction with DB that requires, to cause it to commit the changes. My final err to overcome was my own mistake in fabricating the account_table - The logged_in_server field was set for auto-increment and was key - so having more than one 0 was tripping it up.

Working code, db.py:

Code: Select all

import random
import os
import urllib
import sys

try:
        import settings
except(ImportError):
        sys.stdout.write("Content-Type: text/html\r\n\r\n")
        print "UNKNOWN Error&trade;:"
        print "Failed to import settings module.  <br>"
        print "You probably just checked out the server and have not customized it yet. <br>"
        print ""
        print "Copy settings.sample.py to settings.py and edit it to your liking."
        print "Also, make sure that you have created a units/ folder that contains these four"
        print "files: default.save, factions.xml, units.csv and vegastrike.config."
        print "For each 'mod', make a folder inside the units/ folder containing a copy of"
        print "those four files, with custom mod settings."
        print ""
        sys.exit(0)


#CGI Helper function to replace buggy FieldStorage
def urlDecode(args):
        argsplit = args.split('&')
        arglist = {}
        for arg in argsplit:
                if not arg:
                        continue
                argsp= arg.split('=')
                name = urllib.unquote(argsp[0])
                if len(argsp)>1:
                        value = urllib.unquote(argsp[1].replace('+',' '))
                else:
                        value = ''
                arglist[name] = value
        return arglist

class DBError(RuntimeError):
        def __init__(self, args):
                RuntimeError.__init__(self, args)

# Catch this error for problems with input.
class DBInputError(DBError):
        def __init__(self, args):
                DBError.__init__(self, args)

class DBBase:
        def __init__(self, mod):
                if mod not in settings.mods:
                        raise DBInputError,"Invalid mod '"+mod+"'"
                self.moddata = settings.mods[mod]
                self.mod = self.moddata['path']
                self.modkey = mod
                self.data_path = settings.data_path
                if self.mod:
                        self.data_path += '/' + self.mod
        def check_password(self, username, password):
                return False
        def modify_account(self, username, type="llama.begin", faction="confed"):
                self.save_account(username, self.get_default_save(type, faction),
                        self.get_default_csv(type))

        def save_account(self, username, save, csv):
                pass
        def get_login_info(self, user, password):
                pass
        def hash_password(self, password):
                import hashlib
                if settings.password_hash_methode == 'md5':
                        return hashlib.md5(password).hexdigest()
                elif settings.password_hash_methode == 'sha':
                        return hashlib.sha1(password).hexdigest()

        def compare_password(self, hash, password):
                phash = self.hash_password(password)
                if len(hash)<len(phash):
                        return password == hash
                else:
                        return phash.lower() == hash.lower()

        def check_string(self, s):
                if not s:
                        return "" # Should return something at least.
                        #raise DBInputError, "All fields must be non-empty."
                for c in s:
                        oc = ord(c)
                        if oc < 32 or oc >= 127:
                                raise DBInputError, "Invalid character "+str(oc)+" in field."
                return s

        def get_server(self, system):
                servers = self.moddata['servers']
                return servers.get(system,
                        servers.get(system.split('/')[0],
                        servers.get('', "0.0.0.0:4364")))
        def open_default_file(self, file):
                return open(self.data_path+'/'+file,"rb")

        def get_default_save(self, shiptype='', faction=''):
                try:
                 f=self.open_default_file("network.save")
                except IOError:
                 try:
                  f=self.open_default_file("New_Game")
                 except IOError:
                  try:
                   f=self.open_default_file("accounts/default.save")
                  except IOError:
                   try:
                    f=self.open_default_file("default.save")
                   except:
                    raise DBError, "Not able to open the default saved game."
                s = f.read()
                f.close()
                if not shiptype:
                        return s
                caret = s.find('^')
                if caret != -1:
                        caret = s.find('^', caret+1)
                eol = s.find('\n')
                if caret == -1 or eol == -1:
                        s='Crucible/Cephid_17^\n'
                        caret = len(s)-2
                        eol = len(s)-1
                if not faction:
                        lastsp = s.rfind(' ',0,eol)
                        faction = s[lastsp+1:eol]
                s=s[:caret]+"^"+shiptype+" "+str(120000000000+random.uniform(-10000,10000))+" "+str(40000000+random.uniform(-10000,10000))+" "+str(-110000000000+random.uniform(-10000,10000))+" "+faction+s[eol:]
                return s
        def get_default_csv(self, shiptype):
                try:
                        unfp=self.open_default_file('units.csv')
                except IOError:
                        try:
                                unfp=self.open_default_file('units/units.csv')
                        except:
                                raise DBError, "Not able to open units.csv"
                type_dat = unfp.readlines()
                unfp.close()
                if not shiptype:
                        return type_dat
                s = ''
                if len(type_dat)>3:
                        s += (type_dat[0])
                        s += (type_dat[1])
                for line in type_dat[2:]:
                        # Turrets do not work server-side, so avoid any ships with turrets for now.
                        if (not len(line) or line.find("turret")!=-1):
                                continue
                        name=""
                        if line.find("./weapons")!=-1:
                                continue
                        if line[0]=='"':
                                endl=line[1:].find('"')
                                if endl!=-1:
                                        name=line[1:1+endl] 
                        else:
                                endl=line.find(",")
                                if endl!=-1:
                                        name=line[:endl]
                        if (len(name) and name.find("__")==-1 and name.find(".blank")==-1 and name!="beholder"):
                                if name==shiptype:
                                        s += line
                                        return s;
                raise DBError, "Can not find information for unit '"+shiptype+"'"

class FileDB(DBBase):
        def __init__(self, config, mod):
                DBBase.__init__(self, mod)
                self.storage_path = config['storage']
                if self.storage_path[-1]=='/':
                        self.storage_path = self.storage_path[:-1]
                try:
                        os.mkdir(self.storage_path)
                except:
                        pass
                if self.mod:
                        try:
                                os.mkdir(self.storage_path+'/'+self.mod)
                        except:
                                pass
                self.storage_path += '/'
                self.user_path = self.storage_path
                if self.mod:
                        self.storage_path += self.mod + '/'
                if config.get('create_user',True):
                        self.create_user=True
                else:
                        self.create_user=False
        def check_password(self, username, password, can_create = False):
                success=False
                try:
                        f=open(self.user_path+username+".password","rb")
                        s=f.read()
                        f.close()
                        if self.compare_password(s, password):
                                success=True
                except IOError:
                        if self.create_user and can_create:
                                f=open(self.user_path+username+".password","wb")
                                f.write(self.hash_password(password))
                                f.close()
                                success=True
                        else:
                                success=False
                return success
        # Checks a string for valid username characters.
        def check_string(self, s):
                if not s:
                        raise DBInputError, "You must fill out all fields"

                for c in s:
                        if not (c.isalnum() or c=='_' or c=='-' or c=='.' or c=='$'):
                                raise DBInputError, "Invalid character "+c+" in input "+s

                if s.find("..")!=-1 or s.find(".xml")!= -1 or s.find(".save")!=-1 or s.find("accounts")!=-1 or s.find("default")!=-1:
                        raise DBInputError, "Invalid character . in input "+s

                return s

        def save_account(self, username, save, csv):
                o=open(self.storage_path+username+".save","wb")
                o.write(save)
                o.close()
                o=open(self.storage_path+username+".xml","wb")
                o.write(csv)
                o.close()

        def get_login_info(self, user, password):
                result={}
                f=None
                if not self.check_string(user):
                        return None
                try:
                        f=open(self.user_path+user+".password","rb")
                        tpass=f.read()
                        f.close()
                        if self.compare_password(tpass, password):
                                try:
                                        f=open(self.storage_path+user+".save","rb")
                                        result['savegame']=f.read()
                                        f.close()
                                except IOError:
                                        result['savegame']=None
                                try:
                                        f=open(self.storage_path+user+".xml","rb")
                                        result['csv']=f.read()
                                        f.close()
                                except IOError:
                                        result['csv']=None
                                try:
                                        f=open(self.storage_path+user+'.logged',"rb")
                                        result['logged_in_server']=f.read()
                                        f.close()
                                except IOError:
                                        result['logged_in_server']=None
                                return result
                except IOError:
                        pass
                return None

        def set_connected(self, user, isconnected):
                if not self.check_string(user):
                        return
                f=open(self.storage_path+user+'.logged',"wb")
                if isconnected:
                        f.write("1")
                f.close()#empty file

class debugcursor:
        def __init__(self,curs):
                self.curs=curs
        def execute(self,query,tup):
                fp = open('/tmp/persistent/vegastrike_forum/debugacct.txt','at')
                try:
                        fp.write(str(query%tup))
                except:
                        fp.write('Error: '+repr(query)+' % '+repr(tup))
                fp.close()
                self.curs.execute(query,tup)
        def fetchone(self):
                return self.curs.fetchone()

class debugconn:
        def __init__(self,db):
                self.db=db
        def cursor(self,*args):
                return debugcursor(self.db.cursor(*args))

class MysqlDB(DBBase):
        def __init__(self, config, mod):
                DBBase.__init__(self, mod)
                if 1: #try:
                        import MySQLdb
                        self.conn = MySQLdb.connect(
                                host   = config['host'],
                                port   = int(config.get('port','3306')),
                                passwd = config['passwd'],
                                user   = config['user'],
                                db     = config['db'])
                        self.dict_cursor = MySQLdb.cursors.DictCursor
                else: #except:
                        self.conn = None
                        self.dict_cursor = None
                self.user_table = config.get('user_table', 'accounts')
                self.account_table = config.get('account_table', 'accounts')

                if config.get('create_user',True):
                        self.create_user = True
                else:
                        self.create_user = False

        def check_password(self, username, password, can_create=False):
                username=username.replace(' ','_')
                c = self.conn.cursor() #self.dict_cursor
                c.execute('SELECT user_id, user_password FROM ' + 
                        self.user_table + ' WHERE username=%s',
                        (username,) )
                result = c.fetchone()
                if result and result[0]:
                        return self.compare_password(result[1], password)
                else:
                        if self.create_user and can_create:
                                c = self.conn.cursor()
                                c.execute('INSERT INTO '+self.user_table +
                                        ' (username, user_password) VALUES ' +
                                        ' (%s, %s)',
                                        (username, self.hash_password(password))) 
                                self.conn.commit()
                                return True
                        else:
                                return False

        def save_account(self, username, save, csv):
                #print save
                #print csv
                if not save:
                        raise DBError('Empty save file')
                elif not csv:
                        raise DBError('Empty csv file')
                c = self.conn.cursor()
                whereadd=''
                username=username.replace(' ','_')
                if self.user_table != self.account_table:
                        c.execute('SELECT logged_in_server FROM '+self.account_table +
                                ' WHERE username=%s AND modname=%s',
                                (username, self.modkey))
                        row = c.fetchone()
                        if not row:
                                c.execute('INSERT INTO '+self.account_table +
                                        ' (username, modname, csv, savegame, logged_in_server)'+
                                        ' VALUES (%s, %s, %s, %s, 0)',
                                        (username, self.modkey, csv, save)) 
                                self.conn.commit()
                        else:
                                #print ('UPDATE ' + self.account_table +
                                #       ' SET savegame=%s, csv=%s WHERE username=%s AND modname=%s' %
                                #       (save, csv, username, self.modkey))
                                c.execute('UPDATE ' + self.account_table +
                                        ' SET savegame=%s, csv=%s WHERE username=%s AND modname=%s',
                                        (save, csv, username, self.modkey)) 
                                self.conn.commit()
                else:
                        c.execute('UPDATE ' +self.user_table+
                                'SET savegame=%s, csv=%s WHERE username=%s',
                                (save, csv, username) )
                        self.conn.commit()

        def get_login_info(self, username, password):
                username=username.replace(' ','_')
                c = self.conn.cursor(self.dict_cursor)
                if self.user_table != self.account_table:
                        if self.check_password(username, password, False):
                                c.execute('SELECT logged_in_server, savegame, csv FROM ' +
                                        self.account_table + ' WHERE username=%s AND modname=%s',
                                        (username,self.modkey))
                                ret = c.fetchone()
                                if not ret:
                                        return {'savegame':None,
                                                'csv': None,
                                                'logged_in_server':None}
                                return ret
                else:
                        c.execute('SELECT logged_in_server, user_password, savegame, csv FROM ' +
                                self.user_table + ' WHERE username=%s',
                                (username,))
                        result = c.fetchone()
                        if (result):
                                if self.compare_password(result['user_password'], password):
                                        return result
                return None

        def set_connected(self, user, isconnected):
                user=user.replace(' ','_')
                c = self.conn.cursor()
                logged_in_str = '0'
                if isconnected:
                        logged_in_str = '1'
                if self.user_table != self.account_table:
                        c.execute('UPDATE '+self.account_table+' SET logged_in_server='+
                                logged_in_str+' WHERE username=%s', (user,) ) 
                        self.conn.commit()
                else:
                        c.execute('UPDATE '+self.user_table+' SET logged_in_server='+
                                logged_in_str+' WHERE username=%s', (user,)  ) 
                        self.conn.commit()

def connect(config, mod):
        if config['type'] == 'file':
                return FileDB(config, mod)
        elif config['type'] == 'mysql':
                return MysqlDB(config, mod)
        else:
                raise DBError('invalid database type: '+str(dbconfig.type))
I'm thinking now the tables can be expanded to suit future purposes, and once I've learned how to talk to mysql with php, can have a pretty user signup form on the go... Can theoretically extract data too, meaning can has page indicating users online, and possibly where they are one day..
Last edited by Eye~R on Thu Apr 24, 2014 2:49 am, edited 1 time in total.
Multiplayer Server Offline. Copy ony testing rig semi-funcitonal.
User Signup Offline.
Server Health Shows old data from last snapshot before the server downed.

If you have any issues you can usually find me in #vegastrike on freenode.
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Vegaserver enhancements

Post by ezee »

yeh man , good job !
:wink:

I have downloaded phpbb3 and a space theme ( check your PM box )
I am actually working with the market API , that will be an important piece of the MMO
in a near future .

I try to imagine how insert it in the networkcode , slowly .
All i know is where the updates or tick() will occur in the game , it's in the same
place than the visual , audio and network updates .

I'll soon try something cool with the market .
( i started to deal some weed in the moon , but shhhhh..... -> http://forums.vega-strike.org/viewtopic ... 50#p137150)
:lol:

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Post Reply