summaryrefslogblamecommitdiff
path: root/merge/handler.py
blob: 151af1b193feef769f354dfc8e42fb4ad00881a8 (plain) (tree)





























                                                                                                                                                                                                                                                                    
                 









































































































                                                                    
                                                                                                                      

                                                     
                                                 






























































































































































































































                                                                                                                                 
                                                                                                                                



































































                                                                                
#!/usr/bin/python
## This script reads files and process data.

# SQL Table data
sqltable="`merge`.`landoffire`"
sqltable2="`merge`.`accounts`"

# Merge configuration
# These values are inexact, a real report is done later. Tweak as needed.
pollgp=500000.0  # How many GP in total will be given? Value is approx. (default: 250,000)
pollit=1000000.0 # How many Item Points in total will be given? Value is approx. (default: 500,000)
lvadjs=12        # Level adjustment Value (magic number, default: 8)

# List all GM or cheated accounts
# If a player cheated and gave themselves 1 billion GP, in bank or in char,
# That will raise global money count, making legit players get less rewards.
gm=["2000127", "2000064", "2000070", "2000474", "2000000", "2000664", "2000464", "2000799", "2001232", "2000390", "2000106", "2000029", "2003587", "2002046", "2000005", "2000740", "2004480"] # Exclude all GM accounts (and ex-GM too). 2004480 was too suspicious

## Below this line, only change baseitem() function
acf,reg,stg,ath=[],[],[],[]

class Account:
  def __init__(self, ide, nam):
    self.id=ide
    self.name=nam.replace("\\", "\\\\").replace("'", "\\'").replace("\"", "\\\"").replace(";", "")
    self.gp=0
    self.pts=0
    self.lv=0 # level ^ 1.2 to valorize higher level chars (experience principle)
    self.mpt=0 # MobPt
    self.password="0000"
    self.salt="1"

allinv={}
allit=0
allgp=0
allmp=0
allbp=0
allacc={}

report_it=0
report_ban=0
report_acc=0
report_exp=0

# Assume every dye'ed item is the base item to prevent pseudo-rarity
def baseitem(idt):
    if (idt >= 2050 and idt <= 2059):
        idt=1202 # Cotton shirt
    elif (idt >= 2060 and idt <= 2069):
        idt=624 # V Neck
    elif (idt >= 2070 and idt <= 2079):
        idt=564 # T Neck
    elif (idt >= 2080 and idt <= 2089):
        idt=720 # Silk Robe
    elif (idt >= 2090 and idt <= 2099):
        idt=688 # Tanktop
    elif (idt >= 2100 and idt <= 2109):
        idt=632 # Cotton skirt
    elif (idt >= 2120 and idt <= 2129):
        idt=689 # Short tanktop
    elif (idt >= 2110 and idt <= 2119):
        idt=586 # Cotton shorts
    elif (idt >= 2130 and idt <= 2139):
        idt=723 # Desert Hat
    elif (idt >= 2140 and idt <= 2149):
        idt=724 # Cotton Headband
    elif (idt >= 2150 and idt <= 2159):
        idt=735 # Cotton Boots
    elif (idt >= 2160 and idt <= 2169):
        idt=741 # Cotton Gloves
    elif (idt >= 2170 and idt <= 2179):
        idt=771 # Miniskirt
    elif (idt >= 2180 and idt <= 2189):
        idt=648 # Cotton Trousers
    elif (idt >= 2190 and idt <= 2199):
        idt=1255 # Rabbit Ears
    elif (idt >= 2200 and idt <= 2209):
        idt=4028 # Wizard Hat
    elif (idt >= 2210 and idt <= 2219):
        idt=4030 # Bowler Hat
    elif (idt >= 2220 and idt <= 2229):
        idt=798 # Sorcerer Robe
    elif (idt >= 2230 and idt <= 2239):
        idt=800 # Bowler Hat Brown
    elif (idt >= 2240 and idt <= 2249):
        idt=870 # Red Dress
    elif (idt >= 2250 and idt <= 2259):
        idt=660 # Cotton Cloth
    elif (idt >= 5000 and idt <= 6000):
        idt=798 # SorcererRobe*
    elif (idt >= 8000 and idt <= 8003):
        idt=8029 # Savior Armor
    elif (idt >= 8055 and idt <= 8060):
        idt=8029 # Savior Armor
    return idt

def adjusted_itemvalue(your, total):
    global allit
    #mult=(total*float(allit))
    value=float(your)/float(total)

    return int( value*10000 )


query=open("query.sql", "w")
query.write("CREATE TABLE "+sqltable+" (\n\
    ACNAME VARCHAR(32) NOT NULL PRIMARY KEY,\n\
    GP INT(3) NOT NULL,\n\
    XP INT(3) NOT NULL,\n\
    INV INT(3) NOT NULL\n\
    )\n\
\n\
CREATE TABLE "+sqltable2+" (\n\
    ACNAME VARCHAR(32) NOT NULL PRIMARY KEY,\n\
    MD5 VARCHAR(32) NOT NULL\n\
    )\n")

##########################################
##########################################
##  FIND THE TOTAL AMOUNT OF ALL ITEMS  ##
##########################################
##########################################
acf=open("account.txt", "r")
reg=open("accreg.txt", "r")
stg=open("storage.txt", "r")
ath=open("athena.txt", "r")

# Before all, create accounts and add them to allacc
for line in acf:
    a=line.split('\t')
    if (a[12] != "0"): # Banned? We should skip this account
        report_ban+=1
        gm.append(a[0])
        continue
    if (a[0] in gm): # GM? We should skip, too
        continue
    aid=a[0]
    allacc[aid]=Account(aid, a[1].replace('\\', '\\\\').replace('\n', '').replace('\'', '\\\'').replace('\"', '\\\"'))
    allacc[aid].password=a[2].split('$')
    allacc[aid].password=str(allacc[aid].password[1])
    allacc[aid].salt=str(allacc[aid].password[0])
    report_acc+=1

# Storage
for line in stg:
    a=line.split('\t')
    b=a[0].split(',')
    if b[0] in gm: # GM/Ban? Skip this storage check
        continue
    b=a[1].split(',')
    i=1
    while (True):
        try:
            # sanitize item:
            b[i]=baseitem(b[i])
            try:
                allinv[b[i]]+=int(b[i+1])
            except:
                allinv[b[i]]=int(b[i+1])
            allit+=int(b[i+1])
            i+=10
        except:
            try:
                print "Code error at storage: %s, %s" % (b[i], b[i+1])
            except:
                pass
            break

# Inventories
for line in ath:
    a=line.split('\t')
    b=a[1].split(',')
    if b[0] in gm: # GM/Ban? Skip this inventory check
        continue
    b=a[15].split(',')
    i=1
    while (True):
        try:
            # sanitize item:
            b[i]=baseitem(b[i])
            try:
                allinv[b[i]]+=int(b[i+1])
            except:
                allinv[b[i]]=int(b[i+1])
            allit+=int(b[i+1])
            i+=11
        except:
            try:
                print "Code error at inventory: %s" % (b[i+1])
            except:
                pass
            break

    # While we are at it, we should save account data too
    aid=a[1].split(',')
    aid=aid[0]
    # Prepare Money
    agp=a[4].split(',')
    agp=agp[2]
    # Prepare Experience
    alv=a[3].split(',')
    alv=(float(alv[1])**1.2)/3.0
    # Do you have mob points?
    apt=0
    for c in a[18].split(' '):
        d=c.split(',')
        if d[0] == "Mobpt":
            apt+=int(int(d[1])/10) # TODO: Magical adjustment
            allmp+=int(d[1])
        if d[0] == "BOSS_POINTS":
            apt+=int(d[1])*5
            allbp+=int(d[1])
    try:
        allacc[aid].gp+=int(agp)
        allacc[aid].lv+=int(alv)-(allacc[aid].lv/10)
        allacc[aid].mpt+=int(apt)
    except KeyError:
        #print "%s account id on char data, but account was banned" % (aid)
        pass

acf.close()
reg.close()
stg.close()
ath.close()
##########################################
##########################################
##    FIND THE TOTAL AMOUNT OF GOLD!    ##
##########################################
##########################################
acf=open("account.txt", "r")
reg=open("accreg.txt", "r")
stg=open("storage.txt", "r")
ath=open("athena.txt", "r")
# Athena
for line in ath:
    a=line.split('\t')
    b=a[1].split(',')
    if b[0] in gm: # Banned? Skip from allgp pool
        continue
    b=a[4].split(',')
    try:
        allgp+=int(b[2])
    except:
        print "Code error at gp-athena: %s" % (b)

# Bank
for line in reg:
    a=line.split('\t')
    if a[0] in gm: # Banned? We disregard this account
        continue
    b=a[1].split(',')
    try:
        if (b[0]=="#BankAccount"):
            agp=int(b[1])
    except:
        try:
            err=True
            for opt in a[1].split(' '):
                if ("#BankAccount" in opt):
                    agp=int(opt.replace(',', '').replace('\n', '').replace(' ', '').replace('#BankAccount', ''))
                    err=False
                    break
            if err:
                print "error in accreg fallback: %s" % str(a[1].split(' '))
                raise Exception
        except:
            print "Code error at accreg: %s" % (b)
            pass

    # While we are at it, we should save that GP to accounts too
    aid=a[0]
    try:
        allacc[aid].gp+=int(agp)
        allgp+=int(agp)
    except KeyError:
        pass

acf.close()
reg.close()
stg.close()
ath.close()
##########################################
##########################################
##    START TREATING EACH account =D    ##
##########################################
##########################################
acf=open("account.txt", "r")
stg=open("storage.txt", "r")
ath=open("athena.txt", "r")
rd1=0




#### Process and save every inventory & storage entry
# Storage
for line in stg:
    a=line.split('\t')
    a=a[0].split(',')
    if b[0] in gm: # GM/Ban? Skip this storage check
        continue
    accid=b[0]
    b=a[1].split(',')
    i=1
    while (True):
        try:
            # sanitize item:
            b[i]=baseitem(b[i])
            allacc[accid].pts+=adjusted_itemvalue(b[i+1], allinv[b[i]])
            i+=10
        except:
            break

# Inventories
for line in ath:
    a=line.split('\t')
    b=a[1].split(',')
    if b[0] in gm: # GM/Ban? Skip this inventory check
        continue
    accid=b[0]
    b=a[15].split(',')
    i=1
    while (True):
        try:
            # sanitize item:
            b[i]=baseitem(b[i])
            allacc[accid].pts+=adjusted_itemvalue(b[i+1], allinv[b[i]])
            i+=11
        except:
            break













rd2=0
rd3=0
for aid in allacc:
    acc=allacc[aid]
    # Adjust money value: If you hold 100% of LoF money (currently estimated in 1,088,273,287 GP) you would receive 250 thousands
    rd1+=acc.gp
    acc.gp=int( acc.gp*pollgp/allgp )
    # Adjust item points (currently estimated in 2,427,618) to be within a controlled poll of 1 million points
    acc.pts=int ( acc.pts*pollit/allit )
    rd2+=acc.pts
    # Convert level in experience points
    acc.lv=int ( (acc.lv**1.2)*lvadjs )
    # Add mobpoints to level, with a smaller value
    acc.lv=acc.lv+(acc.mpt/14)
    report_exp+=acc.lv

    # We are done with adjustment. Skip empty values:
    if acc.gp == acc.lv and acc.lv == acc.pts and acc.pts == 0:
        continue
    # Otherwise, we are done for good, save to query
    query.write("INSERT INTO %s (ACNAME, GP, XP, INV) VALUES ('%s',%d,%d,%d)\n" % (sqltable, acc.name, acc.gp, acc.lv, acc.pts ))
    query.write("INSERT INTO %s (ACNAME, MD5, SALT) VALUES ('%s','%s','%s')\n" % (sqltable2, acc.name, acc.password, acc.salt ))
    rd3+=1

    # Generate account entry on another table

acf.close()
stg.close()
ath.close()
##########################################
##########################################
##           GENERATE REPORT!           ##
##########################################
##########################################
for key in allinv:
    report_it+=allinv[key]

## Summary
print("Found %d items (item kinds: %d)" % (report_it ,len(allinv)) )
if (allit - report_it != 0):
    print("Pragma %d items" % allit)
print("Counted %d GP" % allgp)
if (allgp-rd1 != 0):
    print("Pragma: %d GP (diff: %d)" % (rd1, allgp-rd1))
print("Found %d valid and %d banned accounts" % (report_acc, report_ban) )
#print("Disregard: %s" % str(gm))

print("Total mob points: %d" % allmp)
print("Total boss points: %d" % allbp)
print("Total experience given: %d" % report_exp)

print("Total accounts exported: %d" % rd3)

print("-----")
# Riches Summary
r=open("riches.csv", "w")
rd=0
for a in allacc:
    r.write('%s,%s,%d\n' % (a, allacc[a].name.replace(',','+'), allacc[a].gp))
    rd+=allacc[a].gp
r.close()

print("Riches theoretical check: %d" % int(allgp*pollgp/allgp))
print("Riches real check: %d" % rd)

# Items Summary
ip=open("items.csv", "w")
ipd=0
for a in allacc:
    ip.write('%s,%s,%d\n' % (a, allacc[a].name.replace(',','+'), allacc[a].pts))
    ipd+=allacc[a].pts
ip.close()

print("Item Points theoretical: %d" % int(allit*pollit/allit))
print("Item Points real check: %d" % rd2)
if ipd != rd2:
    print("Item points distributed: %d" % ipd)

# All Items
ip=open("inventory_all.csv", "w")
for a in allinv:
    ip.write('%s,%d\n' % (a, allinv[a]))
ip.close()

# Levels
r=open("level_table.csv", "w")
for a in allacc:
    r.write('%s,%s,%d\n' % (a, allacc[a].name.replace(',','+'), allacc[a].lv))
r.close()