Skip to main content

Small script for one of the plarium game

few notes about google games.
Goggle informed that access to the all games be closed after June, 30. I played "Pirates: Tides of fortune" and decided to limit my game time using small script. Detail is below.
Some history
First internet games were updated network games only. 15 years ago internet connection requires a lot of money and nobody had a problem with lagging of the other players. Usually games uses personal communication protocol. Warbirds, Aces High and Eve online use this way.
Next part use a browser and trivial HTTP protocol. One of the popular game in this area is travian . Travian player uses browser and every browser (PC, cell phone, tablet) can be used for playing. Of course, popularity of the game is related to graphics. Trivial HTTP does not have good power in this and other technology is used for this side. One of them is Flash . Unfortunately flash requires a lot of CPU : "Pirates" was near to froze at my old celeron with 512MB. I hope next generation of browser's games will user WebGL.
Investigation
Modern HTTP games uses AJAX for sending data from client's application to the server. This one way decreases load at server side and increases client responses. I started to run ngrep session (ngrep is included in the most of linux distro) and capture some data from client to server and back:
POST /PiratesGp/Segment01/segment.ashx HTTP/1.1.
Host: 209.190.96.226.
Connection: keep-alive.
Content-Length: 158.
sign-code: d92d1d781e82623efc9125a18994876c.
Origin: https://rulesofwargame.com.
signin-userid: gpxxxxxxxxxxxxxxxxxxxxxxxxx
server-method: AutoRefresh.
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36.
client-ver: 405.
signin-authseed: fxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
signin-authkey: fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
locale-name: en-US.
content-type: text/html.
Accept: */*.
Accept-Encoding: gzip,deflate,sdch.
Accept-Language: en-US,en;q=0.8.
.
{"q":[1111,11111,11111,1111],"r":44007,"n":{"n":1},"y":null,"t":1372655066490,"u":1372653774360,"g":1061130,"chat":{"i":9353,"s":63507239220890,"r":["m.1","a.21"]}}


Look like games uses Google OAuth but I'm not sure. Anyway only next variables is important for developing bot: sign-code, signin-userid, signin-authseed, signin-authkey. Last three header fields are related to authorization. First variable ( sign-code) is interested. This one is used for security reason and is equal to md5sum from body and secret string. Body is JSON converted to string. Final python function is calculated as:
def generateRequestSignature(str1, str2):
    ''' Generate request signature  from '''
    return  hashlib.md5(("The Matrix has you..."+ str1+ str2).encode('ascii')).hexdigest()

After this trivial and long work should be done related to the client command. Each command should be investigated and added to the script. In the answer above "t" is a Unix time , "u" time from last login, "g" command id, "q" island position on the global map.
After this we can create a simple class for this game:
class PiratesClient:
    ''' Main class for generating daemon'''
    def __init__(self, profile): 
        ''' Constructor of the client. Set values of the headers and defaults paramaters fields.  
            Accept authSeed, authKey, userId, commandid, and user delta'''
        self.headers = { 
            "User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:10.0.5) Gecko/20100101 Firefox/10.0.5 Iceweasel/10.0.5",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
            "Accept-Language": "uk,ru;q=0.8,en-us;q=0.5,en;q=0.3",
            "Accept-Encoding": "gzip",
            "DNT": "1",
            "Connection": "keep-alive",
            "Content-Type": "text/html",
            "locale-name": "en-US"
        }
        #####################
        # read config file 
        #####################
        # system configuration
        self.config  = configparser.RawConfigParser()
        self.config.read('pirates.ini','UTF-8')

        # user configuration (dynamic create if not exists)
        self.config_user  = configparser.RawConfigParser()
        if os.path.exists('pirates_'+str(profile.my_uid)+'.ini'):
            self.config_user.read('pirates_'+str(profile.my_uid)+'.ini','UTF-8')
        else:
            with open('pirates_'+str(profile.my_uid)+'.ini', 'w') as configfile:
                self.config_user.add_section('client')
                self.config_user.set('client', 'commandid', "12345")            
                self.config_user.write(configfile)
                configfile.close()
                self.config_user.read('pirates_'+str(profile.my_uid)+'.ini','UTF-8')
         

        self.profile = profile
        self.commandId = int(self.config_user['client']['commandid'])
        self.version = int(self.config['game']['version'])
       
        self.headers["client-ver"] = self.version
        self.headers["signin-authSeed"] = profile.authSeed
        self.headers["signin-authKey"] = profile.authKey
        self.headers["signin-userId"] = profile.userId

        self.userdelta = 45678
        self.userId = profile.userId
        self.authKey = profile.authKey
        self.piratesurl = SERVER_IP
        self.userQ = profile.userQ
        self.userSegment = profile.userSegment
        self.params = {"q": self.userQ, "r":self.commandId, "v": self.version}
        self.connection = http.client.HTTPConnection(self.piratesurl)
        self.cachedUserRefresh = None

and creating gear at the heaven :
            
    def StartConversionJob(self):
        """  function for convert lumber and gold to gear (1 h for now)"""
        requesttime = round(time.time()*1000)
        new_g_value = round(requesttime-self.userdelta)
        self.commandId=self.commandId+1

        data = [{ # user ID list
            "t":requesttime,
            "u":new_g_value,
            "q":self.params["q"],
            "g":1089306,
            "r":self.commandId,
            "o":{"f":1, "i":3},
        }]

I think that creating other function is not so hard task. command
 ngrep -W byline -d eth0 host
helps to retrieve information. I have not made any changes at the client or server sides of this application. Simple result
Most of the function is already done. It is not a hard task but requires a lot of time. If you would like to create a similar game by yourself you can try. Server for this kind of game is priced under 20 $/month. (Original server uses Windows Vista Home edition, look like virtual host). Other is your time and initiative. You need some painter and musics skills fro creating frontend and some skill fro backend. Also I would like to say that game programming it is not gold mine , but you success in your hands. If anybody interested I can add few articles about creating this kind of games by using modern framework

I've add  few articles about investigating flash  games . First part is http://skhohlov.blogspot.com/2017/04/plarium-again.html

Comments

  1. Replies
    1. sorry I was busy and have not sped time for browser game. If you are would like to know I can update this article

      Delete
  2. Hi, thanks for this post.

    In the method generateRequestSignature, what are the parameters str1 & str2 ?

    ReplyDelete
  3. Hi man. I'm getting e{"c":-100,"m":"{\"i\":\"1.2.3.4\",\"d\":1478136694177}"} response when sending commands like SendUnit.

    ReplyDelete
  4. Hello everyone,
    I've not played this games for few years.
    If it is so important for you I can refresh this script

    ReplyDelete
  5. hello everyone,
    I've checked current status and would like to inform that crypting mechanic is changed. I've checked js scripts and have not came across creating control data function. Look like this one https://cdn01.x-plarium.com/pirates/content/ui/skin_parts/buttons/attackWindow/buttonAttackBig/01.swf or this one :
    https://cdn01.x-plarium.com/pirates/client/ppen/uc_11_10_1619_636143915938688580.swf
    I've switched to backend programming programming and idea generating. I'm not ready to spend a lot of time on this task and I 'm not sure in win. Anyway anybody can known how computer and internet are working and can say "programming is not magic". Also only legal ways are used, i'm not a crime.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Gabi, can we share knowledge on this topic please?

      Delete
    3. New function is also simple. developers have added id of aut for various type of auth(email, google, faceboot etc)

      Delete
  6. hi
    im trying to do something similar for another game of same company (stormfall age of war) on his facebook server. im trying to create a interface to avoid using the flash game and do it through a GUI but dont able to send the user data to connect.
    by now im using basic for try to programm it. any ideas will be welcoming. thanks in advance

    ReplyDelete
    Replies
    1. I'm not interesting in developing flash games. I've done it for fun. I detected that sum control code is changed. If some one is ready to use flash decompiler I can help.

      Delete
    2. Have written new article with default steps for sorting out writting script procedure.

      Delete
    3. Hi, Imtrested too and want to share what I know...But thats more once you are logged in...

      Delete
    4. Check this one: http://skhohlov.blogspot.com/2017/04/plarium-again.html I've written few articles about this one.

      Delete

Post a Comment

Popular posts from this blog

Update grub using dracut

Fixing grub using dracut Last kernel update was not successful to me. Centos can not boot with next messages:  [ 180.098802] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 180.610167] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 181.121619] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 181.633093] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 182.144831] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 182.656146] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 183.167306] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts [ 183.678755] dracut-initqueue[376]: Warning: dracut-initqueue timeout - starting timeout scripts  Of course simples way  is creating  linux  usb stick  and fix it. But dracut
  debian,  amavis,  virus inside archive   One my client asked informed me, that amavis skips some files types. mail server configuration is really simple: Postfix as SMTP server and  amavis working as context filter. Also amavis runs spamassasin and clamd antivirus. Amavis gets files from attachment and unpack it. lha file is not detected. short investigation First I deceided to run amavis  in debug mode and verify how virus passed postix+amavis.  root@newserver:/var/lib/amavis# /etc/init.d/amavis stop [ ok ] Stopping amavis (via systemctl): amavis.service. root@newserver:/var/lib/amavis# /etc/init.d/amavis debug Trying to run amavisd-new in debug mode. Debug mode inform about loaded plugins: ' Nov 13 22:07:23.335 newserver. /usr/sbin/amavisd-new[40334]: Found decoder for .cpio at /bin/pax Nov 13 22:07:23.336 newserver. /usr/sbin/amavisd-new[40334]: Found decoder for .tar at /bin/pax Nov 13 22:07:23.336 newserver. /usr/sbin/amavisd-new[40334]

Postfix can not start via systemd (simple fix)

Solving problem related to systemd process I like postfix.   This is really smart and secure mail server. I'm helping above  dozen clients around the world and  tunning  postfix is really fun task. This morning I was downgrading postfix  to the stable version for one of the my friends and come across interesting issue.  root@newserver:/etc/init.d# systemctl status postfix ● postfix.service Loaded: masked (/dev/null; bad) Active: inactive (dead) since вт 2017-06-13 14:35:41 EEST; 1h 48min ago Main PID: 25145 (code=exited, status=0/SUCCESS) чер 13 14:47:09 newserver systemd[1]: Stopped postfix.service. чер 13 14:47:29 newserver systemd[1]: Stopped postfix.service. чер 13 14:58:22 newserver systemd[1]: Stopped postfix.service. чер 13 14:58:23 newserver systemd[1]: Stopped postfix.service. чер 13 15:05:20 newserver systemd[1]: Stopped postfix.service. чер 13 15:29:06 newserver systemd[1]: Stopped postfix.service. чер 13 15:29:06 newserver systemd[1]: Stopp