rcpd/encode.py

79 lines
3.5 KiB
Python

import shared
import random
import tables
def encode(name,clas,gun,armour,trait,spec,talent,rank=-1,cap=-1,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False,seed=-1):
print(name,clas,gun,armour,trait,spec,talent,rank,cap,xp, key,moh,pcc,cob,lsa,rem,seed)
if rank==-1: # actually means gun wasn't given, so shift them
gun,armour,trait,spec,talent,rank=-1,gun,armour,trait,spec,talent
gtalent=tables.clas[clas][talent]
if clas>9: clas+=5 # Shift tech/Alice up to their positions - always
# ... And do it before modifying clas below.
if gun!=-1:
#encode gun into class
if clas==9: clas+=gun+1 # Because 9 outside is Mav, and 9 inside is GLWM
if clas==8: clas+=gun-5
rank-=1 # This actually DOES affect part 2 for some fucking reason
cap=max(cap,(rank)//3+(rank>9)) #Sanity-check
code1=encode_data(clas,armour,trait,spec,talent,rank,cap,xp, key,moh,pcc,cob,lsa,rem,seed)
code2=validate_data(name,clas,armour,trait,spec,gtalent,rank,cap,xp, key,moh,pcc,cob,lsa,rem)
shared.trace(code1,code2)
code=shared.combine(code1,code2)
shared.trace(code)
return shared.delimit(shared.scramble(code),'-')
def encode_data(clas,armour,trait,spec,talent,rank,cap=-1,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False,seed=-1):
if clas==6: armour=2 # Borg is heavy borg
if clas==8: clas=6; armour=0 # LR WM is light borg
if clas==9: clas=6; armour=1 # GL WM is med borg
seed,clas=rand(seed,clas)
print(rank,cap)
rank,cap=adjust_rank(rank,cap,key,moh,pcc)
print(rank,cap,key,moh,pcc)
code1=0
weight=1
for n in list(zip(tables.weights,[xp//10,rank,cap,cob,lsa,rem,clas,armour,trait,spec,talent])):
shared.trace(code1,weight,n[0],n[1])
weight*=n[0]
code1+=n[1]*weight
return str(seed)+shared.fill0s(code1,9)+str(xp%10)
def validate_data(name,clas,armour,trait,spec,talent,rank,cap=0,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False):
# gtalent is now looked up outside, before class modification - because I've adjusted that table to be more useful in general.
if isinstance(name,str): name=hash_name(name)
fac1=[171,142,175,157,167,150,149,151,153,165]
fac2=[169,170,166,173,158,177,161,180,186,159] # I don't understand these, but I hope they work.
code2=name*(spec+1) +(trait+4)*(trait+6) +(rank+1)*(xp+1) +(talent+1)*43*fac1[name%10] -(clas+1)*(241+fac2[name%10]) -(rem+1)*50 +(key+1)*4 +(moh+1)*9 +(pcc+1)*19 +(cob+1)*39 +(lsa+1)*79 +(armour+1)*159
code2+=100*(cap+1)*(code2%1000) # To be honest I don't understand any of this. It's just random nonsense.
while code2>99999:
code2=code2%100000+code2//100000
return shared.fill0s(code2,5)
############################
# SUPPORTING FUNCTIONS BELOW
############################
def getval(char):
vals='_9483726150rstlmeaiuonycdpjkhgxwfvqzb(-[.!' # szszss'
#vals='_5698472031aeioyusptndchbrxvzjmlkwgfq-!.([' # meebs'
if char in vals: return vals.index(char)+1
return 43*len(char.encode('utf-8')) # Apparently multibyte chars do this
def hash_name(name):
parsed=name.lower().replace(')','(').replace(']','[')
checksum=0
for i in range(len(parsed)):
checksum+=getval(parsed[i])*((i+1)%3+1)
return checksum
def adjust_rank(rank,cap=-1, key=False,moh=False,pcc=False):
rank+=key*2+moh # Invalid if rank <11, but whatever
if rank>8: #Can't have PCC below r10, and there are only two possible cap states after that
cap=(cap==4)*2+pcc+1 # I don't know why pcc is encoded like this, I would have thought cap would behave normally if not pcc, but nope.
return rank,cap
def rand(seed,clas):
if seed>-1: n=seed
else: n=int(random.random()*5)*2
if clas>9: return n+1,clas-10
return n,clas