EventScripts (CS:S) -> Source Python (CS:S)

General discussion for off-topic subjects.
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

EventScripts (CS:S) -> Source Python (CS:S)

Postby bobkid » Sat Sep 19, 2015 8:40 pm

Hi there. Since I've been experiencing lots of problems since the last game update where the steam ID format was changed I've been wondering if I could just kick out eventscripts and install source python instead. We have a few custom written files in python on our server for admin menus, items etc.
Due to the new steam ID3 they won't work since the plugins need to get a hold of steam ID2.

I've found the part of eventscripts but I don't know how to make it grab the new ID format.. If someone could help me there that would be really kind. On the other hand who knows how long we could keep this going so someday soon we gotta change to source python I'd guess. But right now we need a quick fix T_T

btw this is part of the playerlib.py

Syntax: Select all

def _uniqueid(self, botname=False):

""" Returns a unique id for the player. Call without underscore, i.e.: player.uniqueid([botname]) """

# We start with the player's Steam ID

uniqueid = es.getplayersteamid(self.userid)

if 'LAN' in uniqueid:

# LAN players

address = es.createplayerlist(self.userid)[self.userid]['address'].split(':')[0]

uniqueid = 'LAN_%d:%s' % (len(address), address.replace('.',''))

elif uniqueid == 'BOT' and botname:

# BOTs with names attached

uniqueid = ('BOT_%s' % es.getplayername(self.userid)).upper()

return uniqueid
stonedegg
Senior Member
Posts: 141
Joined: Sun Aug 12, 2012 11:45 am

Postby stonedegg » Sat Sep 19, 2015 8:56 pm

If all your scripts are using playerlib.uniqueid to authenticate players, you could modify the function:

Syntax: Select all

uniqueid = steamid3to2(es.getplayersteamid(self.userid))


And add the following to the bottom of playerlib.py

Syntax: Select all

def steamid3to2(steamid):
account_id = int(steamid[5:-1])
universe = account_id % 2
return 'STEAM_0:%s:%s'% (universe, (account_id - universe) // 2)



By doing this playerlib.uniqueid will return the steamid2 of the player.
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Sat Sep 19, 2015 8:58 pm

Hello and welcome!

I can think of two options to solve the SteamID issues.
  1. You can update all your databases by using the functions specified here: http://forums.eventscripts.com/viewtopic.php?f=90&t=47646
  2. You can try out this script. That guy over there reported that it's causing issues with his server, but I honestly don't see why.
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Sun Sep 20, 2015 10:47 am

stonedegg wrote:If all your scripts are using playerlib.uniqueid to authenticate players, you could modify the function:

Syntax: Select all

uniqueid = steamid3to2(es.getplayersteamid(self.userid))


And add the following to the bottom of playerlib.py

Syntax: Select all

def steamid3to2(steamid):
account_id = int(steamid[5:-1])
universe = account_id % 2
return 'STEAM_0:%s:%s'% (universe, (account_id - universe) // 2)



By doing this playerlib.uniqueid will return the steamid2 of the player.


this will insert the steamid2 to databanks when using a command on a player such as giving levels fro example.
I actually intend to stay with the steamid3 but the thing is even after converting the old steamids to new in our databanks the plugins will still use the steamid2 format. So what i actually want is to rewrite the uniqueid fetching in the playerlibrary so it fetches the steamid3 so it does not always need to convert. with this i just have to convert the steamids in our current database once and then always keep going with the new steamid formatation

another thing that is bugging me is when I trigger a ban it will fetch the steamid3 convert those to steamid2 and save it in the bans config. so when the server loads this config it will match the steamid2 with the connecting user and won't block this individual because they don't use steamid2 but steamid3 instead.
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Sun Sep 20, 2015 12:39 pm

Syntax: Select all

def steamid2to3(steamid):
prefix, a, b = steamid.split(':')
return '[U:1:%s]'% (int(b)*2+int(a))


basically if the playerlibrary does this (fetching and working with steamid3(that's what evenscripts is missing)) that would be a huge step forward. converting the database's steamid content to steamid3 is another thing.

would it work if i write in the playerlibrary to use steamid2to3 and steamid3to2 and than compare those? like:

steamid3to2 == steamid2to3
stonedegg
Senior Member
Posts: 141
Joined: Sun Aug 12, 2012 11:45 am

Postby stonedegg » Sun Sep 20, 2015 3:28 pm

If you convert all your databases to use the steamid3 format, then there is nothing in playerlib you need to change. playerlib.uniqueid uses es.getplayersteamid, which will return the new format.
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Mon Sep 21, 2015 6:39 pm

right..... so the player databank is sqlite. does someone happen to be familiar with that? the steamID is stored in there as VARCHAR. is there a way i can pick those up and convert them? i don't think there is a way but i'm a noob in those thing maybe someone knows something i don't :)

or maybe it is possible to calculate the steamid2 to steamid3 which will compare identical IDs and set the newer one equal to the old one?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Mon Sep 21, 2015 7:07 pm

Did you look at the links I posted? There are conversion functions to convert SteamID2 to SteamID3 and vice-versa. Also, did you test the script I posted on the EventScripts forums? I'm pretty sure it will solve your issues.
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Mon Sep 21, 2015 11:06 pm

yes and i did try them but it didn't work. just saw that there was an update to those, gonna try it by tomorrow. thanks for telling :)

just a question out of curiosity: what are those rb and wb things you were talking about in one of the topics? i'm interested in this kind of stuff and i want to learn more about programming :)
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Tue Sep 22, 2015 6:52 am

It defines the mode how you want to open the file. rb means read-binary and wb means write-binary.
More information: https://docs.python.org/3.4/library/functions.html#open
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Tue Sep 29, 2015 8:12 pm

Syntax: Select all

steam = 'STEAM_'
def steamid2to3(steamid):
prefix, a, b = steamid.split(':')
return '[U:1:%s]'% (int(b)*2+int(a))

plik = open('old.db', 'rb').readlines()
rep = open('new.db', 'wb')
for i in plik:
if steam in i:
steam_position = -(i[::-1].index('S')+1)
print i[steam_position:-2]
old_steam_id = i[steam_position:-2]
rep.write(i.replace(old_steam_id, steamid2to3(old_steam_id)))
else:
rep.write(i)


rep.close()


so i could use this in a py file and load that in the autoexec of the server? just need to do it once or am i mistaken?
also can i get trouble with the .db databases when my databanks are sqlite?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Tue Sep 29, 2015 8:58 pm

Well, the script he made was working for his pickle database. I doubt this is even working with pickle databases that use a different protocol. SQLite3 databases won't work for sure. Try this one instead:

Syntax: Select all

from __future__ import with_statement

import re

# Path to the old database
OLD_DATABASE = 'old.db'

# Path for the new database
NEW_DATABASE = 'new.db'

RE_STEAMID = re.compile(r'(STEAM_\d:\d:\d+)')

def steamid2to3(steamid):
prefix, a, b = steamid.split(':')
return '[U:1:%s]'% (int(b)*2+int(a))

def match_converter(match):
steamid = match.group(1)
try:
return steamid2to3(steamid)
except:
print('Failed to convert SteamID "{0}".'.format(steamid))

return steamid

print('Reading old database...')
with open(OLD_DATABASE, 'rb') as f:
data = f.read()

print('Converting database...')
data = RE_STEAMID.sub(match_converter, data)

print('Saving database...')
with open(NEW_DATABASE, 'wb') as f:
f.write(data)

print('Done!')
It's a cleaner and more general (and probably faster) solution.

You can run that script with any Python 2.x interpreter. Make sure that you adapt the OLD_DATABASE and NEW_DATABASE constants. And please create a backup before running this script. It actually does that for you unless you set both constants to the same value. In that case it will overwrite your existing database!
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Wed Sep 30, 2015 12:01 pm

Code: Select all

Reading old database...
Converting database...
Traceback (most recent call last):
  File "C:\Users\my_user\Desktop\steamidfix.py", line 31, in <module>
    data = RE_STEAMID.sub(match_converter, data)
TypeError: cannot use a string pattern on a bytes-like object


right... the steamIDs are stored as VARCHAR(30)....
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Wed Sep 30, 2015 12:06 pm

You need to make it a string. To be more precise: you need to make it a raw string, because you are using backslashes.

Syntax: Select all

OLD_DATABASE = r'C:\Users\my_user\Desktop\asd.sqlite'
Or if you don't use backslashes, you can also use this:

Syntax: Select all

OLD_DATABASE = 'C:/Users/my_user/Desktop/asd.sqlite'
bobkid
Junior Member
Posts: 8
Joined: Sat Sep 19, 2015 8:28 pm
Location: Germany

Postby bobkid » Wed Sep 30, 2015 12:13 pm

Syntax: Select all

OLD_DATABASE = 'C:\\Users\\my_user\\Desktop\\asd.sqlite'

that worked for me. just went full retard at some point there xD
edited my previous post, noticed again that the steamid is stored as VARCHAR(30) in the databank..... now how do i tackle this situation?

and what I don't understand is how does the script know where to fetch the steamIDs in the databank?

Syntax: Select all

RE_STEAMID = re.compile(r'(STEAM_\d:\d:\d+)')
does it search for strings in that format? how does it split the string and use single parts of it for calculation with the formula?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Wed Sep 30, 2015 1:25 pm

Oh, it doesn't seem to work with Python 3.x. Try this one instead:

Syntax: Select all

import re

# Path to the old database
OLD_DATABASE = 'old.db'

# Path for the new database
NEW_DATABASE = 'new.db'

RE_STEAMID = re.compile(b'(STEAM_\d:\d:\d+)')

def steamid2to3(steamid):
prefix, a, b = steamid.split(b':')
return '[U:1:{0}]'.format(int(b)*2+int(a))

def match_converter(match):
steamid = match.group(1)
try:
return steamid2to3(steamid).encode()
except:
print('Failed to convert SteamID "{0}".'.format(steamid))

return steamid

print('Reading old database...')
with open(OLD_DATABASE, 'rb') as f:
data = f.read()

print('Converting database...')
data = RE_STEAMID.sub(match_converter, data)

print('Saving database...')
with open(NEW_DATABASE, 'wb') as f:
f.write(data)

print('Done!')
The script is searching for the regular expression pattern and replaces all occurrences by using the match_converter() function.
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Wed Sep 30, 2015 1:30 pm

However, I just tried reading the database and it says that it's malformed. I guess we can't simply replace the occurences.

Return to “Whatever”

Who is online

Users browsing this forum: No registered users and 22 guests