rendered paste body# Terry Fisherman's Friend 1.5.3
# Terry Donahugh (terrydonahugh@gmail.com)
# Selling this software (verbatim or modified) is NOT allowed
# Distributing modified versions of this software is NOT allowed
# No warranties of any kind!
# Copyright holders will bear no liability for any use of this software
import gaiaonline
import getpass
import random
import time
import md5
import sys
def selectFish(tod, rareEnabled, level, human):
rareFish = None
if tod == "night":
rareFish = 8
elif tod == "day":
rareFish = 4
elif tod in ["sunset", "twilight"]:
rareFish = 9
large = [10,11,14]
medium = [2,3,13]
small = [0,1,12]
trash = [5,6,7]
rare = [rareFish]
fish = [trash, small, medium, large, rare]
x = 0
if rareEnabled:
x = 1
toFish = []
fishCount = [ [0, 0, 9-x, 9, x],
[0, 4-x, 11, 3, x],
[0, 11-x, 6, 1, x] ]
fishMax = [ [18, 54, 18, 9, x],
[32, 54, 11, 3, x],
[51, 42, 6, 1, x] ]
# select maximum possible
if not human:
counts = fishCount[level]
print counts
for class_, count in enumerate(counts):
for i in xrange(count):
toFish.append(random.choice(fish[class_]))
# a human like fishing thingo
if human:
print "using human mode"
totalFish = 0
maximums = fishMax[level][:]
while len(toFish) != 18:
class_ = random.randint(0,4)
if maximums[class_] != 0:
toFish.append( random.choice( fish[class_] ))
maximums[class_] -= 1
print "tofish:", toFish
return toFish
class Fisher(gaiaonline.GameClient):
def __init__(self, session, gameSession, networkThread, level = "durem"):
gaiaonline.GameClient.__init__(self, gameSession, networkThread)
self.session = session
self.roomMethod = "fishinggame"
self.level = "durem"
self.gameName = "gaiafishing003"
self.logonSession = "5"
# this is the 4.10 key
self.gameMD5 = "fdb92f1dc388cd886f8e5e5e7c78fb79"
self.baitString = "baitf"
self.fishGameReady = False
self.initFishNames()
self.timeOfDayStrings = ["day", "sunset", "night", "twilight"]
self.avatarString = "http://avatar2.gaiaonline.com/gaia/members/" + self.gameSession.getAvatar() + ".swf"
self.round = 0
self.human = False
def displayProgress(self):
if self.printFunc == sys.stdout.write:
sys.stdout.write("\r[ ")
for i in self.status:
sys.stdout.write(i)
sys.stdout.write(" ] ")
sys.stdout.write("%i/18" % (self.fishIdx+1))
sys.stdout.flush()
else:
fishName = self.fishNames[self.toFish[self.fishIdx]]
self._print("Round %i: [%i/18] %s %s" % (self.round, self.fishIdx+1, self.baitDisplay, fishName))
def startFishing(self):
#print "starting fishing"
self.fishGameReady = False
self.round+=1
print "Round", self.round
self.lastFish = "0"
self.fishIdx = 0
self.myFish = [0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
self.callPlugin("G_FISH_PLUGIN", ["501", self.gameMD5, self.gameSession.getSessionID()], self.selectBait)
self.status = ["."] * 18
def selectBait(self, msg):
sushi = msg.decoded[0][3]
if sushi[1] != chr(0x05):
self.emergency("Could not fetch bait/rod information.")
return
baitTypes = sushi[2].split("|")
baitTypes = [ x.split(":") for x in baitTypes ]
self.baitTypes = baitTypes
rodTypes = []
try:
rodTypes = sushi[3].split("|")
except:
print "you don't have a rod"
self.quit()
return
timeOfDay = sushi[4]
self.styleSheetID = int(sushi[5])
bait = None
count = None
try:
bait, count = random.choice(baitTypes)
except:
self.emergency("Out of bait!", self.Fatal)
return
baitStrings = { "100001" : "baitf",
"100002" : "baitd",
"100003" : "baita" }
#print baitTypes
#print bait
self.baitString = baitStrings[bait]
print "Using bait:", self.baitString[-1]+".",
self.baitDisplay = ""
print "Bait left:",
for idx, b in enumerate(baitTypes):
self.baitDisplay+="["+baitStrings[b[0]][-1]+":"+b[1]+"]"
print "["+baitStrings[b[0]][-1]+":"+b[1]+"]",
print
self.bait = bait
self.callPlugin("G_FISH_PLUGIN", ["500",
self.bait, # bait type
"0", # save flag
self.gameSession.getSessionID()],
self.getFishInfo)
def getFishInfo(self, message):
sushi = message.decoded[0][3]
sushiCommand = sushi[0]
sushiStatus = sushi[1]
if sushiCommand == "E":
self.emergency("Server side error, try again.")
#print "server side error :("
elif sushiStatus == chr(0x06):
#print "saved game in progress"
self.callPlugin("G_FISH_PLUGIN", ["500",
self.bait, # bait type
"1", # save flag
self.gameSession.getSessionID()],
self.getFishInfo)
elif sushiStatus == chr(0x05):
#print "got fish info"
self.fishSID1 = sushi[2]
self.fishSID2 = sushi[3]
self.timeOfDay = sushi[4]
self.timeOfDayString = self.timeOfDayStrings[int(self.timeOfDay)]
level = 2
keyMap = { "0bec1093f7a3de5a1fb0481a90c72387" : (0, False),
"8537b11bae00996495118be7a6cb899d" : (0, True),
"2d4c488e581879c8bfc0664c35cb2ccc" : (1, False),
"af9d30069c67e56b93c621d4ccb611c4" : (1, True),
"c90b2f8da134c0889936adec6466d290" : (2, False) }
level, rare = keyMap[self.fishSID1]
print "self.human", self.human
self.toFish = selectFish(self.timeOfDayString, rare, level, self.human)
assert(len(self.toFish) == 18)
# shuffle the fishies
random.shuffle(self.toFish)
self.fishGameReady = True
def calculateSecurityNumber(self, saveMsg):
styleSheetID = int(self.styleSheetID)
userID = int(self.gameSession.getUserID())
number = 0
if styleSheetID != 0:
number = userID % styleSheetID
number += int(self.clientID)
idx = 1
while idx < len(saveMsg):
token = str(saveMsg[idx])
number += len(token)
number += token.find("1")
number += token.find("2")
number += token.find("4")
number += token.find("5")
idx += 1
return number
def saveGame(self):
print
m = md5.new()
userID = str(self.gameSession.getUserID())
m.update(self.fishSID1 + userID + self.fishSID2)
sum1 = m.hexdigest()
fishIDs = self.fishIDs
myFish = self.myFish
fishStr= ""
fishCheckStr = ""
for fishID, count in enumerate(myFish):
if count > 0:
fishCheckStr+=str(fishIDs[fishID])+str(count)
fishStr+=str(fishIDs[fishID])+":"+str(count)+"|"
m = md5.new()
m.update(fishCheckStr+self.fishSID2)
sum2 = m.hexdigest()
saveData = ["510", "2", fishStr, sum1, sum2, self.gameSession.getSessionID()]
sn = self.calculateSecurityNumber(saveData)
print "security number", sn
self.callPlugin("G_FISH_PLUGIN", ["510", "2", fishStr, sum1, sum2, self.gameSession.getSessionID(), sn], self.getSaveInfo)
self.fishing = False
self.saveDone = False
def getSaveInfo(self, msg):
sushi = msg.decoded[0][3]
#print sushi
if sushi[1] == chr(0x05):
print "Game saved succesfully"
elif sushi[1] == chr(0x06):
print "debug:", msg.decoded
if sushi[2] == -4:
self.emergency("Session expired.")
else:
print "Game save failed!"
print "debug:", msg.decoded
self.emergency("Game save failed.")
self.saveDone = True
def initFishNames(self):
if self.level == "durem":
self.fishNames = ["White Pebbo Feeder", #0
"Brown Pebbo Feeder", #1
"Blue Stone Biter", #2
"Black Rocque Biter", #3
"Diamondback king", #4
"Can", #5
"Boot",#6
"Tire", #7
"Emeralback Lion", #8
"Rubyback Lion", #9
"Stone Boldur", #10
"Sand Boldur", #11
"Black Pebbo Feeder", #12
"Pyrite Biter", # 13
"Slate Boldur", # 14
"!! ERROR !!"]
#white brown blue black diamond can boot tire emerald rubyback stone sand black pyrite slate
#pebbo pebbo stone rocque back back lion boldur boldur pebbo biter boldur
#feeder feeder biter biter king lion feeder
self.fishIDs = [100014, 100015, 100016, 100017, 100018, 100021, 100020, 100019, 100033, 100032, 100026, 100027, 100038, 100039, 100042, 0]
def playStep(self):
StartGame, WaitForGame, Sync, WaitForSync, Hook, WaitAfterHook, Sync2, WaitForSync2, WaitForFish, Fish, Restart = range(11)
if self.playStage == StartGame:
self.startFishing()
self.playStage = WaitForGame
elif self.playStage == WaitForGame:
if self.fishGameReady:
self.playStage = Sync
elif self.playStage == Sync:
if time.time() - self.syncTime > 30.0:
self.sync()
self.playStage = WaitForSync
else:
self.playStage = Hook
elif self.playStage == WaitForSync:
if not self.syncReady:
if time.time() - self.syncTime > 10.0:
self.emergency("Sync signal timed out. This happens often when the server is very busy.")
self.playStage = Hook
elif self.syncReady:
self.playStage = Hook
elif self.playStage == Hook:
self.hook()
self.displayProgress()
self.hookTime = time.time()
self.hookWait = random.random()*2.0 + 4.0
self.playStage = WaitAfterHook
elif self.playStage == WaitAfterHook:
if time.time() - self.hookTime > self.hookWait:
self.playStage = WaitForFish
elif self.playStage == WaitForFish:
self.gotone(self.toFish[self.fishIdx])
self.displayProgress()
self.fishIdx+=1
if self.fishIdx == 18:
self.saveGame()
self.playStage = Restart
else:
self.playStage = Fish
self.catchTime = time.time()
self.catchWait = random.random()*4.0 + 2.0
elif self.playStage == Fish:
if time.time() - self.catchTime > self.catchWait:
self.playStage = Sync
elif self.playStage == Restart:
if self.saveDone:
self.playStage = StartGame
def hook(self):
self.status[self.fishIdx]="!"
self.sendSushi([["6", self.clientID, self.avatarString, "1", "0", "126.5",
"112.4","1",self.baitString,"hooked",self.lastFish,"0"]],False)
def escape(self):
self.stats[self.fishIx]="X"
self.sendSushi([["6", self.clientID,
self.avatarString, # avatar url
"1", # player number
"0", # update type
"126.5", # map x
"112.4", # map y
"1", # rod type
self.baitString, # bait type
"escape", # bubble type
self.lastFish, # bubble fish
"0" # ?
]],False)
def gotone(self, fishID):
self.myFish[int(fishID)]+=1
self.status[self.fishIdx]="="
fishID = str(int(fishID)+10)
self.sendSushi([["6", self.clientID,
self.avatarString, # avatar url
"1", # player number
"0", # update type
"126.5", # map x
"112.4", # map y
"1", # rod type
self.baitString, # bait type
"gotone", # bubble type
fishID, # bubble fish
"0" # ?
]],False)
self.lastFish = fishID
if __name__ == "__main__":
import sys
username = ""
password = ""
product = "Terry's Fisherman's Friend"
version = "1.5.3"
email = "terrydonahugh@gmail.com"
print product, version
print email
if len(sys.argv) != 3:
print "usage", sys.argv[0], "<username> <password>"
print
sys.stdout.write("enter username: ")
username = sys.stdin.readline().strip()
if len(username) == 0:
sys.exit(0)
password = getpass.getpass("enter password: ")
if len(password) == 0:
sys.exit(0)
else:
username = sys.argv[1]
password = sys.argv[2]
session = gaiaonline.Session()
session.logon(username, password)
gameSession = gaiaonline.GameSession()
gameSession.logon(username, password)
while True:
serverPool = [("72.5.72.56", "Demonic"),
("72.5.72.55", "Angelic"),
("72.5.72.102","Grunny")]
#server = random.choice(serverPool)
server = serverPool[0]
print "Server:", server[1]
networkThread = gaiaonline.GameNetworkThread(server[0])
networkThread.start()
fisher = Fisher(session, gameSession, networkThread)
quitStatus = fisher.run()
if quitStatus == fisher.Fatal:
print "Fatal Error! Halting"
break
if quitStatus == fisher.Restart:
print "Restarting in 30 seconds"
time.sleep(30)
if quitStatus == fisher.QuitRequest:
print "Quiting"
break