From 8e33ce61d93beaf575dbf1b756a62e311f440640 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 20:00:41 +0200 Subject: Adding files as in http://dl.dropbox.com/u/1539068/Tradey.tar.bz2 --- being.py | 30 + config.py | 6 + data/items.xml | 5540 +++++++++++++++++++++++++++++++++++++++++++++++++++++ data/sale.xml | 1 + data/user.xml | 1 + main.py | 1012 ++++++++++ net/__init__.py | 0 net/packet.py | 179 ++ net/packet_out.py | 50 + net/protocol.py | 64 + player.py | 31 + tradey.py | 88 + utils.py | 115 ++ 13 files changed, 7117 insertions(+) create mode 100644 being.py create mode 100644 config.py create mode 100644 data/items.xml create mode 100644 data/sale.xml create mode 100644 data/user.xml create mode 100644 main.py create mode 100644 net/__init__.py create mode 100644 net/packet.py create mode 100644 net/packet_out.py create mode 100644 net/protocol.py create mode 100644 player.py create mode 100644 tradey.py create mode 100644 utils.py diff --git a/being.py b/being.py new file mode 100644 index 0000000..9c51a2b --- /dev/null +++ b/being.py @@ -0,0 +1,30 @@ +def job_type(job): + if (job <= 25 or (job >= 4001 and job <= 4049)): + return "player" + elif (job >= 46 and job <= 1000): + return "npc" + elif (job > 1000 and job <= 2000): + return "monster" + elif (job == 45): + return "portal" + +class BeingManager: + def __init__(self): + self.container = {} + + def findId(self, name): + for i in self.container: + if self.container[i].name == name: + return i + return -10 + +class Being: + def __init__(self, being_id, job): + self.id = being_id + self.name = "" + self.x = 0 + self.y = 0 + self.action = "" + self.job = job + self.target = 0 + self.type = job_type(job) diff --git a/config.py b/config.py new file mode 100644 index 0000000..068d432 --- /dev/null +++ b/config.py @@ -0,0 +1,6 @@ +#server = "server.themanaworld.org" +server = "caliban.homeip.net" +port = 6901 +account = "" +password = "" +character = 0 #slot character is in, 0 for first, 1 for second, 2 for third diff --git a/data/items.xml b/data/items.xml new file mode 100644 index 0000000..1656c73 --- /dev/null +++ b/data/items.xml @@ -0,0 +1,5540 @@ + + + + + + + + hairstyles/hairstyle01.xml + + + hairstyles/hairstyle02.xml + + + hairstyles/hairstyle03.xml + + + hairstyles/hairstyle04.xml + + + hairstyles/hairstyle05.xml + + + hairstyles/hairstyle06.xml + + + hairstyles/hairstyle07.xml + + + hairstyles/hairstyle08.xml + + + hairstyles/hairstyle09.xml + + + hairstyles/hairstyle10.xml + + + hairstyles/hairstyle11.xml + + + hairstyles/hairstyle12.xml + + + hairstyles/hairstyle13.xml + + + hairstyles/hairstyle14.xml + + + hairstyles/hairstyle15.xml + + + hairstyles/hairstyle16.xml + + + hairstyles/hairstyle17.xml + + + hairstyles/hairstyle18.xml + + + + + player_male_base.xml + player_female_base.xml + + + + + + + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + weapon-scythe.xml + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-fist.xml + + + weapon-staff.xml + + + + + + + + + + + + + + + + equipment/head/santahat.xml + + + + + + + + + + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-dagger.xml + weapons/knives/sharpknife-miss1.ogg + + + equipment/chest/leather-male.xml|#573a26,9e7654,d3b79e,ffffff;#b96b3d,fbf5f1 + equipment/chest/leather-female.xml|#412300,603100,8d4900;#ffff00 + + + equipment/head/fancyhat.xml + + + equipment/head/minershat.xml + + + + + equipment/feet/boots-male.xml|#623a34,f0c2b4 + equipment/feet/boots-female.xml|#623a34,f0c2b4 + + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + equipment/hands/generic-male.xml|#202020,505050 + equipment/hands/generic-female.xml|#202020,505050 + + + equipment/hands/generic-male.xml|#4e2e18,c8752f + equipment/hands/generic-female.xml|#4e2e18,c8752f + + + + + + weapon-dagger.xml + + + + + + + + + equipment/head/standardheadband.xml|#563f25,99784c,d8bd86,ffffff + + + equipment/head/silkheadband.xml + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + equipment/chest/leather-male.xml|#443c21,85794a,beb590,ffffff;#824035,d6a19a + equipment/chest/leather-female.xml|#251e06,443c21,71653b,a0945e;#b6574a + + + + + + weapon-axe-blacksmith.xml + + + + + + + + + + + + + + + equipment/hands/generic-male.xml|#202020,c0c0c0,ffffff,ffffff + equipment/hands/generic-female.xml|#202020,c0c0c0,ffffff,ffffff + + + equipment/chest/tnecksweater-male.xml|#a4b2b2,ffffff + equipment/chest/tnecksweater-female.xml|#a4b2b2,ffffff + + + + + + + + weapon-dagger.xml + + + weapon-dagger.xml + + + + + + + + + + weapon-dagger.xml + + + + + + + + + equipment/legs/shorts-male.xml|#a4b2b2,ffffff + equipment/legs/shorts-female.xml|#a4b2b2,ffffff + + + + + weapon-sword-sword.xml + + + + + + + + + + + + equipment/legs/shorts-male.xml|#255367,266c84,68b0c5,ffffff + equipment/legs/shorts-female.xml|#255367,266c84,68b0c5,ffffff + + + + + + + equipment/head/pumpkinhelmet.xml + + + equipment/head/axehat.xml + + + equipment/head/piratehat.xml + + + equipment/head/goggles.xml|#787878,f7f7f7 + + + equipment/head/goggles.xml|#783c00,ff973b + + + equipment/head/circlet.xml + + + equipment/head/eyepatch.xml + + + equipment/head/bandana.xml + + + weapon-scythe.xml + + + equipment/chest/vnecksweater-male.xml|#a4b2b2,ffffff + equipment/chest/vnecksweater-female.xml|#a4b2b2,ffffff + + + equipment/chest/chainmail-male.xml + equipment/chest/chainmail-female.xml + + + equipment/chest/lightplatemail-male.xml|#ddeeff + equipment/chest/lightplatemail-female.xml|#ddeeff + + + equipment/head/tophat.xml + + + equipment/head/funkywinter.xml + + + equipment/head/mushroom.xml + + + equipment/head/shroom.xml + + + + equipment/legs/skirt.xml|#a4b2b2,ffffff + + + equipment/head/xmaself.xml + + + equipment/head/mask.xml + + + + equipment/head/warlordhelm.xml + + + equipment/head/knighthelm.xml + + + equipment/head/infantryhelm.xml + + + equipment/head/crusadehelm.xml + + + + + equipment/legs/chaps-male.xml + equipment/legs/chaps-female.xml + + + equipment/head/cowboywhite.xml + + + equipment/head/cowboyblack.xml + + + equipment/chest/lightplatemail-male.xml|#573f10,9c8226,d3c04b,ffffff + equipment/chest/lightplatemail-female.xml|#573f10,9c8226,d3c04b,ffffff + + + equipment/head/crown.xml + + + equipment/head/devcap.xml|#9999ff + + + equipment/head/devcap.xml|#9999ff + + + equipment/chest/sorcerer-robe-male.xml|#5e7480,f1ffff,ffffff;#2554c7 + equipment/chest/sorcerer-robe-female.xml|#5e7480,f1ffff,ffffff;#2554c7 + + + equipment/chest/sorcerer-robe-male.xml|#000000;#2554c7 + equipment/chest/sorcerer-robe-female.xml|#000000;#2554c7 + + + equipment/chest/robe-male.xml|#5e7480,f1ffff,ffffff + equipment/chest/robe-female.xml|#5e7480,f1ffff,ffffff + + + equipment/chest/robe-male.xml|#000000 + equipment/chest/robe-female.xml|#000000 + + + equipment/chest/robe-male.xml|#804000 + equipment/chest/robe-female.xml|#804000 + + + equipment/head/cap.xml|#d94800 + + + equipment/feet/furboots-male.xml + equipment/feet/furboots-female.xml + + + equipment/head/serf.xml + + + + equipment/chest/warlordplate-male.xml + equipment/chest/warlordplate-female.xml + + + equipment/chest/warlordplate-male.xml|#573f10,9c8226,d3c04b,ffffff + equipment/chest/warlordplate-female.xml|#573f10,9c8226,d3c04b,ffffff + + + + + + + + + + + + + + + + + + equipment/head/gradcap.xml + + + + + equipment/head/nohmask.xml + + + equipment/head/demonmask.xml + + + + + + + + + + + equipment/chest/tanktop-male.xml|#a4b2b2,ffffff + equipment/chest/tanktop-female.xml|#a4b2b2,ffffff + + + equipment/chest/shorttanktop-male.xml|#a4b2b2,ffffff + equipment/chest/shorttanktop-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + equipment/chest/robe-male.xml|#ffffff + equipment/chest/robe-female.xml|#ffffff + + + equipment/head/highpriest-crown.xml + + + equipment/head/monster-skull-helm.xml + + + equipment/head/deserthat.xml|#ffffff + + + equipment/head/standardheadband.xml|#a4b2b2,ffffff + + + equipment/head/gmcap.xml|#bf0e08 + + + equipment/chest/robe-male.xml|#e40a0a + equipment/chest/robe-female.xml|#e40a0a + + + + + + + equipment/legs/assassin-male.xml + equipment/legs/assassin-female.xml + + + + + equipment/feet/boots-male.xml|#212121 + equipment/feet/boots-female.xml|#212121 + + + equipment/feet/boots-male.xml|#a4b2b2,ffffff + equipment/feet/boots-female.xml|#a4b2b2,ffffff + + + + + + + + equipment/hands/generic-male.xml|#a4b2b2,ffffff + equipment/hands/generic-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + equipment/head/pinkiehat.xml + + + equipment/head/fluffyhat.xml + + + + + equipment/chest/assassin-male.xml + equipment/chest/assassin-female.xml + + + equipment/hands/assassin-male.xml + equipment/hands/assassin-female.xml + + + equipment/feet/assassin-boots-male.xml + equipment/feet/assassin-boots-female.xml + + + weapon-staff.xml + + + equipment/head/paladinhelm.xml + + + equipment/head/overlordhelm.xml + + + equipment/head/desert-helmet.xml + + + + + equipment/head/sailor-hat.xml + + + equipment/head/captain-hat.xml + + + equipment/head/terranitehelm.xml + + + equipment/chest/terranite-male.xml + equipment/chest/terranite-female.xml + + + equipment/legs/terranite-male.xml + equipment/legs/terranite-female.xml + + + equipment/head/guyfawkes.xml + + + equipment/head/fairy_hat.xml + + + equipment/legs/miniskirt-male.xml|#a4b2b2,ffffff + equipment/legs/miniskirt-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + equipment/head/witch-doctor-mask.xml + + + equipment/chest/forest-armor-male.xml + equipment/chest/forest-armor-female.xml + + + equipment/chest/valentine-dress.xml|#bf0e08 + + + + + + + + + + equipment/chest/leather-male.xml|#573a26,c9866b,d3b79e,ffffff;#b96b3d,fbf5f1 + equipment/chest/leather-female.xml|#412300,c9866b,8d4900;#ffff00 + + + equipment/feet/bromenalboots-male.xml + equipment/feet/bromenalboots-female.xml + + + equipment/chest/bromenalchest-male.xml|#fbf5e9 + equipment/chest/bromenalchest-female.xml|#fbf5e9 + + + equipment/hands/bromenalgloves-male.xml + equipment/hands/bromenalgloves-female.xml + + + equipment/head/bromenalhelmet.xml + + + equipment/legs/bromenallegs-male.xml + equipment/legs/bromenallegs-female.xml + + + + equipment/chest/sorcerer-robe-male.xml|#ffffff + equipment/chest/sorcerer-robe-female.xml|#ffffff + + + + equipment/head/bowler-hat-brown.xml + + + equipment/head/pinkie-helmet.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + weapon-dagger.xml + + + equipment/chest/cotton-male.xml|#a4b2b2,ffffff + equipment/chest/cotton-female.xml|#a4b2b2,ffffff + + + equipment/head/rangerhat.xml + + + equipment/head/antlerhat.xml + + + equipment/head/christmastree.xml + + + equipment/head/santabeardhat.xml + + + + + + + + + + equipment/head/bunnyears.xml + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/sabre-hit1.ogg + + + equipment/head/mouboohead.xml + + + equipment/head/catears.xml|#774444;#777777 + + + equipment/head/paperbag.xml + + + equipment/head/moubootaurhead.xml + + + equipment/head/parsley-earplugs.xml + + + equipment/head/skullmask.xml + + + + + + + + + + + + + + + + + + + + + + + equipment/head/snowgoggles.xml + + + + + + equipment/override/skeleton.xml + graphics/particles/wisp.particle.xml + + + + + equipment/head/heart-glasses.xml + + + + + + + + + + equipment/head/rabbit-ears.xml|#ffffff + + + equipment/head/eggshell.xml + + + + + equipment/head/operamask.xml + + + equipment/head/jestermask.xml + + + equipment/head/witch-hat.xml + + + equipment/head/goblin-mask.xml + + + + + + + + + equipment/chest/cotton-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/cotton-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/cotton-male.xml|#115511,22aa22,99dd99 + equipment/chest/cotton-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/cotton-male.xml|#222255,6666ff + equipment/chest/cotton-female.xml|#222255,6666ff + + + equipment/chest/cotton-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/cotton-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/cotton-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/cotton-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/cotton-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/cotton-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/cotton-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/cotton-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/cotton-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/cotton-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/cotton-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/cotton-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/cotton-male.xml|#104010,208020,30c030 + equipment/chest/cotton-female.xml|#104010,208020,30c030 + + + + equipment/chest/vnecksweater-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/vnecksweater-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/vnecksweater-male.xml|#115511,22aa22,99dd99 + equipment/chest/vnecksweater-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/vnecksweater-male.xml|#222255,6666ff + equipment/chest/vnecksweater-female.xml|#222255,6666ff + + + equipment/chest/vnecksweater-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/vnecksweater-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/vnecksweater-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/vnecksweater-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/vnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/vnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/vnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/vnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/vnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/vnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/vnecksweater-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/vnecksweater-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/vnecksweater-male.xml|#104010,208020,30c030 + equipment/chest/vnecksweater-female.xml|#104010,208020,30c030 + + + + equipment/chest/tnecksweater-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/tnecksweater-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/tnecksweater-male.xml|#115511,22aa22,99dd99 + equipment/chest/tnecksweater-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/tnecksweater-male.xml|#222255,6666ff + equipment/chest/tnecksweater-female.xml|#222255,6666ff + + + equipment/chest/tnecksweater-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/tnecksweater-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/tnecksweater-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/tnecksweater-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/tnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/tnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/tnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/tnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/tnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/tnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/tnecksweater-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/tnecksweater-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/tnecksweater-male.xml|#104010,208020,30c030 + equipment/chest/tnecksweater-female.xml|#104010,208020,30c030 + + + + equipment/chest/robe-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/robe-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/robe-male.xml|#115511,22aa22,99dd99 + equipment/chest/robe-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/robe-male.xml|#222255,6666ff + equipment/chest/robe-female.xml|#222255,6666ff + + + equipment/chest/robe-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/robe-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/robe-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/robe-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/robe-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/robe-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/robe-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/robe-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/robe-male.xml|#104010,208020,30c030 + equipment/chest/robe-female.xml|#104010,208020,30c030 + + + + equipment/chest/tanktop-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/tanktop-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/tanktop-male.xml|#115511,22aa22,99dd99 + equipment/chest/tanktop-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/tanktop-male.xml|#222255,6666ff + equipment/chest/tanktop-female.xml|#222255,6666ff + + + equipment/chest/tanktop-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/tanktop-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/tanktop-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/tanktop-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/tanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/tanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/tanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/tanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/tanktop-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/tanktop-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/tanktop-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/tanktop-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/tanktop-male.xml|#104010,208020,30c030 + equipment/chest/tanktop-female.xml|#104010,208020,30c030 + + + + equipment/legs/skirt.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/skirt.xml|#115511,22aa22,99dd99 + + + equipment/legs/skirt.xml|#222255,6666ff + + + equipment/legs/skirt.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/skirt.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/skirt.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/skirt.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/skirt.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/skirt.xml|#4f0a76,8010c0,d699f7 + + + equipment/legs/skirt.xml|#104010,208020,30c030 + + + + equipment/legs/shorts-male.xml|#580000,a40000,c02020,ff6060 + equipment/legs/shorts-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/shorts-male.xml|#115511,22aa22,99dd99 + equipment/legs/shorts-female.xml|#115511,22aa22,99dd99 + + + equipment/legs/shorts-male.xml|#222255,6666ff + equipment/legs/shorts-female.xml|#222255,6666ff + + + equipment/legs/shorts-male.xml|#846211,dab333,fffb93,ffffff + equipment/legs/shorts-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/shorts-male.xml|#16486e,498ec5,e4f2fc + equipment/legs/shorts-female.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/shorts-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/legs/shorts-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/shorts-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/legs/shorts-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/shorts-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/legs/shorts-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/shorts-male.xml|#520a7b,8c23c7,ca87ef + equipment/legs/shorts-female.xml|#520a7b,8c23c7,ca87ef + + + equipment/legs/shorts-male.xml|#104010,208020,30c030 + equipment/legs/shorts-female.xml|#104010,208020,30c030 + + + + equipment/chest/shorttanktop-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/shorttanktop-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/shorttanktop-male.xml|#115511,22aa22,99dd99 + equipment/chest/shorttanktop-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/shorttanktop-male.xml|#222255,6666ff + equipment/chest/shorttanktop-female.xml|#222255,6666ff + + + equipment/chest/shorttanktop-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/shorttanktop-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/shorttanktop-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/shorttanktop-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/shorttanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/shorttanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/shorttanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/shorttanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/shorttanktop-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/shorttanktop-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/shorttanktop-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/shorttanktop-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/shorttanktop-male.xml|#104010,208020,30c030 + equipment/chest/shorttanktop-female.xml|#104010,208020,30c030 + + + + equipment/head/deserthat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/deserthat.xml|#115511,22aa22,99dd99 + + + equipment/head/deserthat.xml|#222255,6666ff + + + equipment/head/deserthat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/deserthat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/deserthat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/deserthat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/deserthat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/deserthat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/deserthat.xml|#104010,208020,30c030 + + + + equipment/head/standardheadband.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/standardheadband.xml|#115511,22aa22,99dd99 + + + equipment/head/standardheadband.xml|#222255,6666ff + + + equipment/head/standardheadband.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/standardheadband.xml|#16486e,498ec5,e4f2fc + + + equipment/head/standardheadband.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/standardheadband.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/standardheadband.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/standardheadband.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/standardheadband.xml|#104010,208020,30c030 + + + + equipment/feet/boots-male.xml|#580000,a40000,c02020,ff6060 + equipment/feet/boots-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/feet/boots-male.xml|#115511,22aa22,99dd99 + equipment/feet/boots-female.xml|#115511,22aa22,99dd99 + + + equipment/feet/boots-male.xml|#222255,6666ff + equipment/feet/boots-female.xml|#222255,6666ff + + + equipment/feet/boots-male.xml|#846211,dab333,fffb93,ffffff + equipment/feet/boots-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/feet/boots-male.xml|#16486e,498ec5,e4f2fc + equipment/feet/boots-female.xml|#16486e,498ec5,e4f2fc + + + equipment/feet/boots-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/feet/boots-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/feet/boots-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/feet/boots-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/feet/boots-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/feet/boots-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/feet/boots-male.xml|#4f0a76,8010c0,d699f7 + equipment/feet/boots-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/feet/boots-male.xml|#104010,208020,30c030 + equipment/feet/boots-female.xml|#104010,208020,30c030 + + + + equipment/hands/generic-male.xml|#580000,a40000,c02020,ff6060 + equipment/hands/generic-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/hands/generic-male.xml|#115511,22aa22,99dd99 + equipment/hands/generic-female.xml|#115511,22aa22,99dd99 + + + equipment/hands/generic-male.xml|#222255,6666ff + equipment/hands/generic-female.xml|#222255,6666ff + + + equipment/hands/generic-male.xml|#846211,dab333,fffb93,ffffff + equipment/hands/generic-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/hands/generic-male.xml|#16486e,498ec5,e4f2fc + equipment/hands/generic-female.xml|#16486e,498ec5,e4f2fc + + + equipment/hands/generic-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/hands/generic-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/hands/generic-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/hands/generic-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/hands/generic-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/hands/generic-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/hands/generic-male.xml|#4f0a76,8010c0,d699f7 + equipment/hands/generic-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/hands/generic-male.xml|#104010,208020,30c030 + equipment/hands/generic-female.xml|#104010,208020,30c030 + + + + equipment/legs/miniskirt-male.xml|#580000,a40000,c02020,ff6060 + equipment/legs/miniskirt-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/miniskirt-male.xml|#115511,22aa22,99dd99 + equipment/legs/miniskirt-female.xml|#115511,22aa22,99dd99 + + + equipment/legs/miniskirt-male.xml|#222255,6666ff + equipment/legs/miniskirt-female.xml|#222255,6666ff + + + equipment/legs/miniskirt-male.xml|#846211,dab333,fffb93,ffffff + equipment/legs/miniskirt-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/miniskirt-male.xml|#16486e,498ec5,e4f2fc + equipment/legs/miniskirt-female.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/miniskirt-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/legs/miniskirt-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/miniskirt-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/legs/miniskirt-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/miniskirt-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/legs/miniskirt-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/miniskirt-male.xml|#4f0a76,8010c0,d699f7 + equipment/legs/miniskirt-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/legs/miniskirt-male.xml|#104010,208020,30c030 + equipment/legs/miniskirt-female.xml|#104010,208020,30c030 + + + + + + equipment/head/rabbit-ears.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/rabbit-ears.xml|#115511,22aa22,99dd99 + + + equipment/head/rabbit-ears.xml|#222255,6666ff + + + equipment/head/rabbit-ears.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/rabbit-ears.xml|#16486e,498ec5,e4f2fc + + + equipment/head/rabbit-ears.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/rabbit-ears.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/rabbit-ears.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/rabbit-ears.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/rabbit-ears.xml|#104010,208020,30c030 + + + + equipment/head/wizard-hat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/wizard-hat.xml|#115511,22aa22,99dd99 + + + equipment/head/wizard-hat.xml|#222255,6666ff + + + equipment/head/wizard-hat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/wizard-hat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/wizard-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/wizard-hat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/wizard-hat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/wizard-hat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/wizard-hat.xml|#104010,208020,30c030 + + + + equipment/head/bowler-hat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/bowler-hat.xml|#115511,22aa22,99dd99 + + + equipment/head/bowler-hat.xml|#222255,6666ff + + + equipment/head/bowler-hat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/bowler-hat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/bowler-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/bowler-hat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/bowler-hat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/bowler-hat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/bowler-hat.xml|#104010,208020,30c030 + + + + equipment/chest/sorcerer-robe-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/sorcerer-robe-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/sorcerer-robe-male.xml|#115511,22aa22,99dd99 + equipment/chest/sorcerer-robe-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/sorcerer-robe-male.xml|#222255,6666ff + equipment/chest/sorcerer-robe-female.xml|#222255,6666ff + + + equipment/chest/sorcerer-robe-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/sorcerer-robe-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/sorcerer-robe-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/sorcerer-robe-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/sorcerer-robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/sorcerer-robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/sorcerer-robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/sorcerer-robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/sorcerer-robe-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/sorcerer-robe-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/sorcerer-robe-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/sorcerer-robe-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/sorcerer-robe-male.xml|#104010,208020,30c030 + equipment/chest/sorcerer-robe-female.xml|#104010,208020,30c030 + + + + equipment/head/bowler-hat-brown.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/bowler-hat-brown.xml|#115511,22aa22,99dd99 + + + equipment/head/bowler-hat-brown.xml|#222255,6666ff + + + equipment/head/bowler-hat-brown.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/bowler-hat-brown.xml|#16486e,498ec5,e4f2fc + + + equipment/head/bowler-hat-brown.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/bowler-hat-brown.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/bowler-hat-brown.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/bowler-hat-brown.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/bowler-hat-brown.xml|#104010,208020,30c030 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + equipment/head/candlehelmet.xml + + + + + + + + + equipment/head/yeti-mask.xml + + + equipment/head/wizard-hat.xml + + + + equipment/head/bowler-hat.xml + + + equipment/head/monocle.xml + + diff --git a/data/sale.xml b/data/sale.xml new file mode 100644 index 0000000..374d3f4 --- /dev/null +++ b/data/sale.xml @@ -0,0 +1 @@ + diff --git a/data/user.xml b/data/user.xml new file mode 100644 index 0000000..bc58f62 --- /dev/null +++ b/data/user.xml @@ -0,0 +1 @@ + diff --git a/main.py b/main.py new file mode 100644 index 0000000..3a217cd --- /dev/null +++ b/main.py @@ -0,0 +1,1012 @@ +""" This package implements an Automated Market Bot for "The Mana World" a 2D MMORPG. + + - Currently permissions are defined as: -1 (blocked), 0 (normal user), 5 (seller), 20 (admin). + - An item will only be listed for a period of one week, and can be relisted + for 3 weeks. + - If a Trade in uncompleted within 5 minutes of a Trade Request, it is cancelled + to prevent any disruptions to service. + - The Bot supports the manaplus "right click and buy" feature; if an item is listed + twice for the same price, the first shown in the list will be bought (i.e. the one added earlier). +""" + +import logging +import socket +import sys +import time +import string + +from being import * +from config import * +from net.packet import * +from net.protocol import * +from net.packet_out import * +from player import * +import tradey +import utils + +shop_broadcaster = utils.Broadcast() +trader_state = utils.TraderState() +ItemDB = utils.ItemDB() +player_node = Player('') +beingManager = BeingManager() +user_tree = tradey.UserTree() +sale_tree = tradey.ItemTree() +ItemLog = utils.ItemLog() + +def process_whisper(nick, msg, mapserv): + msg = filter(lambda x: x in string.printable, msg) + user = user_tree.get_user(nick) + broken_string = msg.split() + + if user != -10: + if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. + mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) + return + + if msg == "!list": + # Sends the list of items for sale. + if len(sale_tree.root) != 0: + mapserv.sendall(whisper(nick, "The following items are on sale:")) + else: + mapserv.sendall(whisper(nick, "No items for sale.")) + + for elem in sale_tree.root: + if time.time() - float(elem.get('add_time')) < 604800: # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ + elem.get("itemId") + "|" + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + + elif broken_string[0] == '!selllist': + # Support for 4144's shop (Sell list) + data = '\302\202B1' + + for elem in sale_tree.root: + data += utils.encode_str(int(elem.get("itemId")), 2) + data += utils.encode_str(int(elem.get("price")), 4) + data += utils.encode_str(int(elem.get("amount")), 3) + mapserv.sendall(whisper(nick, data)) + + elif broken_string[0] == '!buyitem': + # 4144 buy command + if len(broken_string) == 4: + if broken_string[1].isdigit() and broken_string[2].isdigit() and broken_string[3].isdigit(): + # Traditional 4144 shop. + item_id = int(broken_string[1]) + price = int(broken_string[2]) + amount = int(broken_string[3]) + for elem in sale_tree.root: + if int(elem.get('amount')) >= amount and int(elem.get('price')) == price and int(elem.get('itemId')) == item_id: + process_whisper(nick, '!buy ' + str(amount) + " " + elem.get('uid'), mapserv) + return + mapserv.sendall(whisper(nick, "Item not found. Please check and try again.")) + else: + mapserv.sendall(whisper(nick, "Syntax incorrect")) + + elif msg == "!info": + # Send information related to a player. + if user == -10: + mapserv.sendall(whisper(nick, "Your current access level is 0.")) + elif int(user.get('accesslevel')) > 0: + mapserv.sendall(whisper(nick, "Your current access level is " + user.get('accesslevel') + ".")) + mapserv.sendall(whisper(nick, "Your have the following items for sale:")) + for elem in sale_tree.root: + if elem.get('name') == nick: + if time.time() - float(elem.get('add_time')) > 604800: + msg = "[expired] [" + else: + msg = "[selling] [" + + msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + + money = int(user.get('money')) + mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) + stall_msg = "You have " + str(int(user.get('stalls')) - int(user.get('used_stalls'))) + " free slots." + mapserv.sendall(whisper(nick, stall_msg)) + + elif broken_string[0] == "!help": + # Sends help information + if len(broken_string) == 1: + mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) + mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) + mapserv.sendall(whisper(nick, "For a detailed description of each command, type !help e.g. !help !buy")) + mapserv.sendall(whisper(nick, "For example:- to purchase an item shown in the list as:")) + mapserv.sendall(whisper(nick, "[selling] [6] 5 [@@640|Iron Ore@@] for 1000gp each")) + mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) + mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) + + elif len(broken_string) == 2: + if broken_string[1] == '!buy': + mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) + elif broken_string[1] == '!list': + mapserv.sendall(whisper(nick, "!list - Displays a list of all items for sale.")) + elif broken_string[1] == '!find': + mapserv.sendall(whisper(nick, "!find or - Simple search to locate an item.")) + elif broken_string[1] == '!buy': + mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) + elif broken_string[1] == '!add': + mapserv.sendall(whisper(nick, "!add - Add an item to the sell list (requires that you have an account).")) + elif broken_string[1] == '!money': + mapserv.sendall(whisper(nick, "!money - Allows you to collect money for any sales made on your behalf.")) + elif broken_string[1] == '!relist': + mapserv.sendall(whisper(nick, "!relist - Allows you to relist an item which has expired.")) + elif broken_string[1] == '!info': + mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) + elif broken_string[1] == '!getback': + mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) + + elif msg == "!money": + # Trades any money earned through item sales. + if user == -10: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + amount = int(user.get('money')) + if amount == 0: + mapserv.sendall(whisper(nick, "You have no money to collect.")) + else: + trader_state.money = nick + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return + player_id = beingManager.findId(nick) + + if player_id != -10: + mapserv.sendall(trade_request(player_id)) + trader_state.timer = time.time() + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + + elif broken_string[0] == "!find": + # Returns a list of items, with the corresponding Item Id - !find or . + if len(broken_string) < 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + items_found = False + item = " ".join(broken_string[1:]) # could be an id or an item name + + if item.isdigit(): # an id + for elem in sale_tree.root: + if ((time.time() - float(elem.get('add_time'))) < 604800) \ + and int(elem.get("itemId")) == int(item): # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + items_found = True + else: # an item name + for elem in sale_tree.root: + if ((time.time() - float(elem.get('add_time'))) < 604800) \ + and item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + items_found = True + + if not items_found: + mapserv.sendall(whisper(nick, "Item not found.")) + + elif msg == '!listusers': + # Admin command - shows a list of all user. + if user == -10: + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + data = '' + + for user in user_tree.root: + name = user.get('name') + accesslevel = user.get('accesslevel') + slots = user.get('stalls') + used_slots = user.get('used_stalls') + money = user.get('money') + data += name+" ("+accesslevel+") "+used_slots+"/"+slots+" "+money+'gp, ' + # Format ManaMarket (20) 2/5 100000gp, + + if len(data) > 400: + mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + data = '' + + mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + + elif broken_string[0] == '!setslots': + # Change the number of slots a user has - !setslots + if user == -10: + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if len(broken_string) < 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if broken_string[1].isdigit(): + slot = int(broken_string[1]) + name = " ".join(broken_string[2:]) + + user_info = user_tree.get_user(name) + + if user_info == -10: + mapserv.sendall(whisper(nick, "User not found, check and try again.")) + return + + user_tree.get_user(name).set('stalls', str(slot)) + mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) + user_tree.save() + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + elif broken_string[0] == '!setaccess': + # Change someones access level - !setaccess + if user == -10: + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if len(broken_string) < 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if (broken_string[1][0] == '-' and broken_string[1][1:].isdigit()) or broken_string[1].isdigit(): + accesslevel = int(broken_string[1]) + name = " ".join(broken_string[2:]) + + user_info = user_tree.get_user(name) + + if user_info == -10: + mapserv.sendall(whisper(nick, "User not found, check and try again.")) + return + + if int(user_info.get('accesslevel')) < int(user.get("accesslevel")) and accesslevel <= int(user.get("accesslevel")): + user_tree.get_user(name).set('accesslevel', str(accesslevel)) + mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) + user_tree.save() + else: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + + elif broken_string[0] == "!adduser": + # A command to give a user access to the bot - !adduser . + if user == -10: + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if len(broken_string) < 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if broken_string[1].isdigit() and broken_string[2].isdigit(): + al = int(broken_string[1]) + stalls = int(broken_string[2]) + player_name = " ".join(broken_string[3:]) + user_tree.add_user(player_name, stalls, al) + mapserv.sendall(whisper(nick, "User Added with " + str(stalls) + " slots.")) + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + elif broken_string[0] == "!add": + # Allows a player with the correct permissions to add an item for sale - !add + if user == -10: + mapserv.sendall(whisper(nick, "You are unable to add items.")) + return + + if len(broken_string) < 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You are unable to add items.")) + return + + if int(user.get("used_stalls")) >= int(user.get("stalls")): + mapserv.sendall(whisper(nick, "You have no free slots. You may remove an item or wait for something to be sold.")) + return + + if broken_string[1].isdigit() and broken_string[2].isdigit(): + amount = int(broken_string[1]) + price = int(broken_string[2]) + item_name = " ".join(broken_string[3:]) + item_id = ItemDB.findId(item_name) + if item_id == -10: + mapserv.sendall(whisper(nick, "Item not found, check spelling.")) + return + + item = Item() + item.player = nick + item.get = 1 # 1 = get, 0 = give + item.id = item_id + item.amount = amount + item.price = price + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return + player_id = beingManager.findId(nick) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) + trader_state.timer = time.time() + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + elif broken_string[0] == "!buy": + # Buy a given quantity of an item - !buy + if len(broken_string) != 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if broken_string[1].isdigit() and broken_string[2].isdigit(): + amount = int(broken_string[1]) + uid = int(broken_string[2]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + if amount > int(item_info.get("amount")): + mapserv.sendall(whisper(nick, "I do not have that many.")) + return + + item = Item() + item.get = 0 # 1 = get, 0 = give + item.player = nick + item.id = int(item_info.get("itemId")) + item.uid = uid + item.amount = amount + item.price = int(item_info.get("price")) + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return + player_id = beingManager.findId(nick) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) + trader_state.timer = time.time() + mapserv.sendall(whisper(nick, "That will be " + str(item.price * item.amount) + "gp.")) + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + elif broken_string[0] == "!removeuser": + # Remove a user, for whatever reason - !removeuser + if user == -10: + return + + if len(broken_string) < 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + player_name = " ".join(broken_string[1:]) + check = user_tree.remove_user(player_name) + if check == 1: + mapserv.sendall(whisper(nick, "User Removed.")) + elif check == -10: + mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) + + elif broken_string[0] == "!relist": + # Relist an item which has expired - !relist . + if user == -10 or len(broken_string) != 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if broken_string[1].isdigit(): + uid = int(broken_string[1]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + if item_info.get('name') != nick: + mapserv.sendall(whisper(nick, "That doesn't belong to you!")) + return + + time_relisted = int(item_info.get('relisted')) + + if int(item_info.get('relisted')) < 3: + sale_tree.get_uid(uid).set('add_time', str(time.time())) + sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) + sale_tree.save() + mapserv.sendall(whisper(nick, "The item has been successfully relisted.")) + else: + mapserv.sendall(whisper(nick, "This item can no longer be relisted. Please collect it using !getback "+str(uid)+".")) + return + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + + elif broken_string[0] == "!getback": + # Trade the player back uid, remove from sale_items if trade successful - !getback . + if user == -10 or len(broken_string) != 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if broken_string[1].isdigit(): + uid = int(broken_string[1]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + if item_info.get('name') != nick: + mapserv.sendall(whisper(nick, "That doesn't belong to you!")) + return + + item = Item() + item.get = 0 + item.player = nick + item.id = int(item_info.get("itemId")) + item.uid = uid + item.amount = int(item_info.get("amount")) + item.price = 0 + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return + player_id = beingManager.findId(nick) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) + trader_state.timer = time.time() + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + +def main(): + logging.basicConfig(filename='logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') + logging.info("Bot Started.") + + account = sys.argv[1] + password = sys.argv[2] + character = sys.argv[3] + + login = socket.socket() + login.connect((server, port)) + print("Login connected") + + login_packet = PacketOut(0x0064) + login_packet.write_int32(0) + login_packet.write_string(account, 24) + login_packet.write_string(password, 24) + login_packet.write_int8(0x03); + login.sendall(str(login_packet)) + + pb = PacketBuffer() + id1 = accid = id2 = 0 + charip = "" + charport = 0 + # Login server packet loop. + while True: + #time.sleep(0.1) + data = login.recv(1500) + if not data: + break + pb.feed(data) + for packet in pb: + if packet.is_type(SMSG_LOGIN_DATA): # login succeeded + packet.skip(2) + id1 = packet.read_int32() + accid = packet.read_int32() + id2 = packet.read_int32() + packet.skip(30) + player_node.sex = packet.read_int8() + charip = utils.parse_ip(packet.read_int32()) + charport = packet.read_int16() + login.close() + break + if charip: + break + + assert charport + + char = socket.socket() + char.connect((charip, charport)) + print("Char connected") + char_serv_packet = PacketOut(CMSG_CHAR_SERVER_CONNECT) + char_serv_packet.write_int32(accid) + char_serv_packet.write_int32(id1) + char_serv_packet.write_int32(id2) + char_serv_packet.write_int16(0) + char_serv_packet.write_int8(player_node.sex) + char.sendall(str(char_serv_packet)) + char.recv(4) + + pb = PacketBuffer() + mapip = "" + mapport = 0 + # Character Server Packet loop. + while True: + data = char.recv(1500) + if not data: + break + pb.feed(data) + for packet in pb: + if packet.is_type(SMSG_CHAR_LOGIN): + packet.skip(2) + slots = packet.read_int16() + packet.skip(18) + count = (len(packet.data)-22) / 106 + for i in range(count): + player_node.id = packet.read_int32() + player_node.EXP = packet.read_int32() + player_node.MONEY = packet.read_int32() + packet.skip(30) + player_node.HP = packet.read_int16() + player_node.MAX_HP = packet.read_int16() + player_node.MP = packet.read_int16() + player_node.MAX_MP = packet.read_int16() + packet.skip(8) + player_node.LEVEL = packet.read_int16() + packet.skip(14) + player_node.name = packet.read_string(24) + packet.skip(6) + slot = packet.read_int8() + packet.skip(1) + print "Character information recieved:" + print "Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s"\ + % (player_node.name, player_node.id, player_node.EXP, player_node.MONEY, player_node.HP, player_node.MAX_HP, player_node.MP, player_node.MAX_MP, player_node.LEVEL) + if slot == int(character): + break + + char_select_packet = PacketOut(CMSG_CHAR_SELECT) + char_select_packet.write_int8(int(character)) + char.sendall(str(char_select_packet)) + + elif packet.is_type(SMSG_CHAR_MAP_INFO): + player_node.id = packet.read_int32() + player_node.map = packet.read_string(16) + mapip = utils.parse_ip(packet.read_int32()) + mapport = packet.read_int16() + char.close() + break + if mapip: + break + + assert mapport + + beingManager.container[player_node.id] = Being(player_node.id, 42) + mapserv = socket.socket() + mapserv.connect((mapip, mapport)) + print("Map connected") + mapserv_login_packet = PacketOut(CMSG_MAP_SERVER_CONNECT) + mapserv_login_packet.write_int32(accid) + mapserv_login_packet.write_int32(player_node.id) + mapserv_login_packet.write_int32(id1) + mapserv_login_packet.write_int32(id2) + mapserv_login_packet.write_int8(player_node.sex) + mapserv.sendall(str(mapserv_login_packet)) + mapserv.recv(4) + + pb = PacketBuffer() + shop_broadcaster.mapserv = mapserv + # Map server packet loop + + while True: + data = mapserv.recv(2048) + if not data: + break + pb.feed(data) + + # For unfinished trades - one way to distrupt service would be leaving a trade active. + if trader_state.Trading.test(): + if time.time() - trader_state.timer > 5*60: + logging.info("Trade Cancelled - Timeout.") + trader_state.timer = time.time() + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + for packet in pb: + if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected + logging.info("Map login success.") + packet.skip(4) + coord_data = packet.read_coord_dir() + player_node.x = coord_data[0] + player_node.y = coord_data[1] + player_node.direction = coord_data[2] + print "Starting Postion: %s %s %s" % (player_node.map, player_node.x, player_node.y) + mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) # map loaded + # A Thread to send a shop broadcast: also keeps the network active to prevent timeouts. + shop_broadcaster.start() + + elif packet.is_type(SMSG_WHISPER): + msg_len = packet.read_int16() - 26 + nick = packet.read_string(24) + message = packet.read_raw_string(msg_len) + logging.info("Whisper: " + nick + ": " + message) + if nick != "guild": + process_whisper(nick, utils.remove_colors(message), mapserv) + + elif packet.is_type(SMSG_PLAYER_CHAT): # server speech + msg_len = packet.read_int16() - 2 + being_id = packet.read_int32() + message = packet.read_string(msg_len) + if "automaticly banned for spam" in message: + time.sleep(3) + + elif packet.is_type(SMSG_BEING_CHAT): # char speech + msg_len = packet.read_int16() - 2 + being_id = packet.read_int32() + message = packet.read_string(msg_len) + + elif packet.is_type(SMSG_WALK_RESPONSE): + packet.read_int32() + coord_data = packet.read_coord_pair() + player_node.x = coord_data[2] + player_node.y = coord_data[3] + + elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0005: + player_node.HP = value + elif stat_type == 0x0006: + player_node.MaxHP = value + elif stat_type == 0x0007: + player_node.MP = value + elif stat_type == 0x0008: + player_node.MaxMP = value + elif stat_type == 0x000b: + player_node.LEVEL = value + print "Level changed: %s" % value + elif stat_type == 0x0018: + print "Weight changed from %s/%s to %s/%s" % (player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + logging.info("Weight changed from %s/%s to %s/%s", player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + player_node.WEIGHT = value + elif stat_type == 0x0019: + print "Max Weight: %s" % value + player_node.MaxWEIGHT = value + + elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0001: + player_node.EXP = value + elif stat_type == 0x0014: + logging.info("Money Changed from %s, to %s", player_node.MONEY, value) + print "Money Changed from %s, to %s" % (player_node.MONEY, value) + player_node.MONEY = value + elif stat_type == 0x0016: + player_node.EXP_NEEDED = value + print "Exp Needed: %s" % player_node.EXP_NEEDED + + elif packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_BEING_VISIBLE)\ + or packet.is_type(SMSG_PLAYER_MOVE) or packet.is_type(SMSG_PLAYER_UPDATE_1)\ + or packet.is_type(SMSG_PLAYER_UPDATE_2): + being_id = packet.read_int32() + packet.skip(8) + job = packet.read_int16() + if being_id not in beingManager.container: + if job == 0 and id >= 110000000 and (packet.is_type(SMSG_BEING_MOVE)\ + or packet.is_type(SMSG_BEING_VISIBLE)): + continue + # Add the being to the BeingManager, and request name. + beingManager.container[being_id] = Being(being_id, job) + requestName = PacketOut(0x0094) + requestName.write_int32(being_id) + mapserv.sendall(str(requestName)) + + packet.skip(8) + + if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): + packet.read_int32() + + packet.skip(22) + + if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): + coord_data = packet.read_coord_pair() + beingManager.container[being_id].dst_x = coord_data[2] + beingManager.container[being_id].dst_y = coord_data[3] + else: + coord_data = packet.read_coord_dir() + beingManager.container[being_id].x = coord_data[0] + beingManager.container[being_id].y = coord_data[1] + beingManager.container[being_id].direction = coord_data[2] + + elif packet.is_type(SMSG_BEING_NAME_RESPONSE): + being_id = packet.read_int32() + if being_id in beingManager.container: + beingManager.container[being_id].name = packet.read_string(24) + + elif packet.is_type(SMSG_BEING_REMOVE): + being_id = packet.read_int32() + if being_id in beingManager.container: + del beingManager.container[being_id] + + elif packet.is_type(SMSG_PLAYER_WARP): + player_node.map = packet.read_string(16) + player_node.x = packet.read_int16() + player_node.y = packet.read_int16() + logging.info("Player warped.") + mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) + + elif packet.is_type(SMSG_BEING_ACTION): + src_being = packet.read_int32() + dst_being = packet.read_int32() + packet.skip(12) + param1 = packet.read_int16() + packet.skip(2) + action_type = packet.read_int8() + + if src_being in beingManager.container: + if action_type == 0: # Damage + beingManager.container[src_being].action = "attack" + beingManager.container[src_being].target = dst_being + + elif action_type == 0x02: # Sit + beingManager.container[src_being].action = "sit" + + elif action_type == 0x03: # Stand up + beingManager.container[src_being].action = "stand" + + elif packet.is_type(SMSG_PLAYER_INVENTORY_ADD): + item = Item() + item.index = packet.read_int16() - inventory_offset + item.amount = packet.read_int16() + item.itemId = packet.read_int16() + item.identified = packet.read_int8() + packet.read_int8() + item.refine = packet.read_int8() + packet.skip(8) + item.equipType = packet.read_int16() + item.itemType = packet.read_int8() + err = packet.read_int8() + + if err == 0: + if item.index in player_node.inventory: + player_node.inventory[item.index].amount += item.amount + else: + player_node.inventory[item.index] = item + + print "Picked up: %s, Amount: %s" % (ItemDB.getItem(item.itemId).name, item.amount) + logging.info("Picked up: %s, Amount: %s", ItemDB.getItem(item.itemId).name, str(item.amount)) + + elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): + index = packet.read_int16() - inventory_offset + amount = packet.read_int16() + + print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) + logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + if index in player_node.inventory: + player_node.inventory[index].amount -= amount + if player_node.inventory[index].amount == 0: + del player_node.inventory[index] + + elif packet.is_type(SMSG_PLAYER_INVENTORY): + player_node.inventory.clear() # Clear the inventory - incase of new index. + packet.skip(2) + number = (len(packet.data)-2) / 18 + for loop in range(number): + item = Item() + item.index = packet.read_int16() - inventory_offset + item.itemId = packet.read_int16() + item.itemType = packet.read_int8() + item.identified = packet.read_int8() + item.amount = packet.read_int16() + item.arrow = packet.read_int16() + packet.skip(8) # Cards + player_node.inventory[item.index] = item + + elif packet.is_type(SMSG_PLAYER_EQUIPMENT): + packet.read_int16() + number = (len(packet.data)) / 20 + for loop in range(number): + item = Item() + item.index = packet.read_int16() - inventory_offset + item.itemId = packet.read_int16() + item.itemType = packet.read_int8() + item.identified = packet.read_int8() + packet.skip(2) + item.equipType = packet.read_int16() + packet.skip(1) + item.refine = packet.read_int8() + packet.skip(8) + item.amount = 1 + player_node.inventory[item.index] = item + + for item in player_node.inventory: + print "Name: %s, Id: %s, Index: %s, Amount: %s." % \ + (ItemDB.getItem(player_node.inventory[item].itemId).name, \ + player_node.inventory[item].itemId, item, player_node.inventory[item].amount) + + elif packet.is_type(SMSG_TRADE_REQUEST): + print "SMSG_TRADE_REQUEST" + name = packet.read_string(24) + logging.info("Trade request: " + name) + + elif packet.is_type(SMSG_TRADE_RESPONSE): + print "SMSG_TRADE_RESPONSE" + response = packet.read_int8() + time.sleep(0.2) + if response == 0: + logging.info("Trade response: Too far away.") + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You are too far away.")) + elif trader_state.money: + mapserv.sendall(whisper(trader_state.money, "You are too far away.")) + trader_state.reset() + + elif response == 3: + logging.info("Trade response: Trade accepted.") + if trader_state.item: + if trader_state.item.get == 1: # add + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + elif trader_state.item.get == 0: # buy + if player_node.find_inventory_index(trader_state.item.id) != -10: + mapserv.sendall(trade_add_item(player_node.find_inventory_index(trader_state.item.id), trader_state.item.amount)) + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + if trader_state.item.price == 0: # getback + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + + elif trader_state.money: # money + amount = int(user_tree.get_user(trader_state.money).get('money')) + mapserv.sendall(trade_add_item(0-inventory_offset, amount)) + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + + elif response == 4: + logging.info("Trade response: Trade cancelled") + trader_state.reset() + + elif packet.is_type(SMSG_TRADE_ITEM_ADD): + print "SMSG_TRADE_ITEM_ADD" + amount = packet.read_int32() + item_id = packet.read_int16() + if trader_state.item and trader_state.money == 0: + if trader_state.item.get == 1: # add + if amount == trader_state.item.amount and item_id == trader_state.item.id: + trader_state.complete = 1 + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + else: + mapserv.sendall(whisper(trader_state.item.player, "Thats not the right item.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif trader_state.item.get == 0: # buy + if amount == trader_state.item.price * trader_state.item.amount and item_id == 0: + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + elif item_id == 0 and amount != trader_state.item.price * trader_state.item.amount: + trader_state.complete = 0 + else: + if item_id == 0: + mapserv.sendall(whisper(trader_state.item.player, "Please verify you have the correct amount of money and try again.")) + else: + mapserv.sendall(whisper(trader_state.item.player, "Don't give me your itenz.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif trader_state.money: # money + mapserv.sendall(whisper(trader_state.money, "Don't give me your itenz.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + logging.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) + # Note item_id = 0 is money + + elif packet.is_type(SMSG_TRADE_ITEM_ADD_RESPONSE): + print "SMSG_TRADE_ITEM_ADD_RESPONSE" + index = packet.read_int16() - inventory_offset + amount = packet.read_int16() + response = packet.read_int8() + + if response == 0: + logging.info("Trade item add response: Successfully added item.") + if trader_state.item: + if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! + if player_node.inventory[index].itemId != trader_state.item.id and \ + amount != trader_state.item.amount: + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + # If Trade item add successful - Remove the item from the inventory state. + if index != 0-inventory_offset: # If it's not money + print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) + logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + if index in player_node.inventory: + player_node.inventory[index].amount -= amount + if player_node.inventory[index].amount == 0: + del player_node.inventory[index] + + elif response == 1: + logging.info("Trade item add response: Failed - player overweight.") + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You are carrying too much weight. Unload and try again.")) + elif response == 2: + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You have no free slots.")) + logging.info("Trade item add response: Failed - No free slots.") + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif packet.is_type(SMSG_TRADE_OK): + print "SMSG_TRADE_OK" + is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other + if is_ok == 0: + logging.info("Trade OK: Self.") + else: + if trader_state.complete: + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + else: + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) + + logging.info("Trade Ok: Partner.") + + elif packet.is_type(SMSG_TRADE_CANCEL): + trader_state.reset() + logging.info("Trade Cancel.") + print "SMSG_TRADE_CANCEL" + + elif packet.is_type(SMSG_TRADE_COMPLETE): + # The sale_tree is only ammended after a complete trade packet. + if trader_state.item and trader_state.money == 0: + if trader_state.item.get == 1: # !add + sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) + user_tree.get_user(trader_state.item.player).set('used_stalls', \ + str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) + + elif trader_state.item.get == 0: # !buy \ !getback + seller = sale_tree.get_uid(trader_state.item.uid).get('name') + item = sale_tree.get_uid(trader_state.item.uid) + current_amount = int(item.get("amount")) + sale_tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) + if int(item.get("amount")) == 0: + user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ + str(int(user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) + sale_tree.remove_item_uid(trader_state.item.uid) + + current_money = int(user_tree.get_user(seller).get("money")) + user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) + + if trader_state.item.price * trader_state.item.amount != 0: + ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) + + elif trader_state.money and trader_state.item == 0: # !money + user_tree.get_user(trader_state.money).set('money', str(0)) + + sale_tree.save() + user_tree.save() + trader_state.reset() + logging.info("Trade Complete.") + print "SMSG_TRADE_COMPLETE" + else: + pass + #print "Unhandled Packet: %s" % hex(packet.get_type()) + + # On Disconnect/Exit + shop_broadcaster.stop() + mapserv.close() + +if __name__ == '__main__': + main() diff --git a/net/__init__.py b/net/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/net/packet.py b/net/packet.py new file mode 100644 index 0000000..4442455 --- /dev/null +++ b/net/packet.py @@ -0,0 +1,179 @@ +import struct + +packet_lengths = [ + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#0x0040 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 3, -1, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2, + 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, +#0x0080 + 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0, + 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6, + 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6, + 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3, +#0x00C0 + 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27, + 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1, + 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2, + 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10, +#0x0100 + 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1, + 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16, + 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1, + 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26, +#0x0140 + 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6, + 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42, + -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182, + 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1, +#0x0180 + 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6, + 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6, + 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4, + 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3, +#0x01C0 + 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28, + 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6, + 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1, + -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10, +#0x2000 + 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +] + +class PacketOut: + def __init__(self, out): + self.buff = "" + self.write_int16(out) + + def __str__(self): + return self.buff + + def write_string(self, string_val, length): + self.buff += string_val.ljust(length, '\0') + + def write_int8(self, value): + self.buff += struct.pack("> 8) % 256 + d_1 = (tmp) % 256 + tmp = y + tmp <<= 4 + d_1 |= (tmp >> 8) % 256 + d_2 = tmp % 256 + # d_2 |= direction + self.buff += chr(d_0) + chr(d_1) + chr(d_2) + +class PacketIn: + def __init__(self, set_data, pkt_type): + self.data = set_data + self.pkttype = pkt_type + self.pos = 0 + + def is_type(self, pkt_type): + return self.pkttype == pkt_type + + def get_type(self): + return self.pkttype + + def read_string(self, length): + msg = self.data[self.pos:self.pos + length] + self.pos = self.pos + length + return msg[:msg.find('\0')] + + def read_raw_string(self, length): + msg = self.data[self.pos:self.pos + length] + self.pos = self.pos + length + return msg + + def read_int8(self): + int_value = struct.unpack("> 2) % 255 + dst_y = self.make_word(struct.unpack("> 6) % 255 + src_y = (self.make_word(struct.unpack("> 4) % 255 + self.pos = self.pos + 5 + return src_x, src_y, dst_x, dst_y + + def read_coord_dir(self): + cdata = self.data[self.pos:self.pos + 3] + x = (self.make_word(struct.unpack("> 6) % 255 + y = (self.make_word(struct.unpack("> 4) % 255 + dir = struct.unpack("= 4 + else: + pktlen = packet_lengths[pkttype] + + if len(self.buff) < pktlen: + raise StopIteration + + packet = PacketIn(self.buff[2:pktlen], pkttype) + self.buff = self.buff[pktlen:] + return packet diff --git a/net/packet_out.py b/net/packet_out.py new file mode 100644 index 0000000..6110f4d --- /dev/null +++ b/net/packet_out.py @@ -0,0 +1,50 @@ +from packet import * +from protocol import * + +def emote(emoteId): + emote_packet = PacketOut(CMSG_PLAYER_EMOTE) + emote_packet.write_int8(emoteId) + return str(emote_packet) + +def whisper(nick, message): + whisp_packet = PacketOut(CMSG_CHAT_WHISPER) + whisp_packet.write_int16(len(message) + 28) + whisp_packet.write_string(nick, 24) + whisp_packet.write_string(message, len(message)) + return str(whisp_packet) + +def chat(text): + chat_packet = PacketOut(CMSG_CHAT_MESSAGE) + mes = player_node.name + " : " + text + chat_packet.write_int16(len(mes) + 4 + 1) + chat_packet.write_string(mes, len(mes) + 1) + return str(chat_packet) + +def sit(val): + sit_packet = PacketOut(CMSG_PLAYER_CHANGE_ACT) + sit_packet.write_int32(0) + if val == True: + sit_packet.write_int8(2) + else: + sit_packet.write_int8(3) + return str(sit_packet) + +def trade_request(being_id): + trade_req_packet = PacketOut(CMSG_TRADE_REQUEST) + trade_req_packet.write_int32(being_id) + return str(trade_req_packet) + +def trade_respond(accept): + trade_respond_packet = PacketOut(CMSG_TRADE_RESPONSE) + if accept == True: + trade_respond_packet.write_int8(3) + elif accept == False: + trade_respond_packet.write_int8(4) + return str(trade_respond_packet) + +def trade_add_item(item_index, amount): + trade_add_packet = PacketOut(CMSG_TRADE_ITEM_ADD_REQUEST) + trade_add_packet.write_int16(item_index + inventory_offset) + trade_add_packet.write_int32(amount) + return str(trade_add_packet) + diff --git a/net/protocol.py b/net/protocol.py new file mode 100644 index 0000000..4a4b74f --- /dev/null +++ b/net/protocol.py @@ -0,0 +1,64 @@ +SMSG_LOGIN_DATA = 0x0069 +SMSG_CHAR_LOGIN = 0x006b +SMSG_CHAR_MAP_INFO = 0x0071 +SMSG_MAP_LOGIN_SUCCESS = 0x0073 +SMSG_MAP_LOGIN_SUCCESS = 0x0073 +CMSG_CHAR_SERVER_CONNECT = 0x0065 +CMSG_CHAR_SELECT = 0x0066 +CMSG_MAP_SERVER_CONNECT = 0x0072 +CMSG_CHAT_WHISPER = 0x0096 +CMSG_CHAT_MESSAGE = 0x008c +CMSG_MAP_LOADED = 0x007d + +SMSG_WHISPER = 0x0097 +SMSG_BEING_CHAT = 0x008d + +SMSG_PLAYER_CHAT = 0x008e +CMSG_PLAYER_CHANGE_ACT = 0x0089 + +SMSG_PLAYER_INVENTORY = 0x01ee +SMSG_PLAYER_INVENTORY_ADD = 0x00a0 +SMSG_PLAYER_INVENTORY_REMOVE = 0x00af +SMSG_PLAYER_EQUIPMENT = 0x00a4 +SMSG_PLAYER_STAT_UPDATE_1 = 0x00b0 +SMSG_PLAYER_STAT_UPDATE_2 = 0x00b1 + +SMSG_BEING_VISIBLE = 0x0078 +SMSG_BEING_MOVE = 0x007b +SMSG_BEING_REMOVE = 0x0080 +SMSG_PLAYER_MOVE = 0x01da +SMSG_PLAYER_WARP = 0x0091 +SMSG_PLAYER_UPDATE_1 = 0x01d8 +SMSG_PLAYER_UPDATE_2 = 0x01d9 +SMSG_BEING_NAME_RESPONSE = 0x0095 # Has to be requested +SMSG_BEING_ACTION = 0x008a + +CMSG_ITEM_PICKUP = 0x009f +CMSG_PLAYER_ATTACK = 0x0089 +CMSG_PLAYER_STOP_ATTACK = 0x0118 +CMSG_PLAYER_CHANGE_DIR = 0x009b +CMSG_PLAYER_CHANGE_DEST = 0x0085 +CMSG_PLAYER_EMOTE = 0x00bf +SMSG_WALK_RESPONSE = 0x0087 + +CMSG_TRADE_REQUEST = 0x00e4 +CMSG_TRADE_RESPONSE = 0x00e6 +CMSG_TRADE_ITEM_ADD_REQUEST = 0x00e8 +CMSG_TRADE_CANCEL_REQUEST = 0x00ed +CMSG_TRADE_ADD_COMPLETE = 0x00eb +CMSG_TRADE_OK = 0x00ef + +SMSG_TRADE_REQUEST = 0x00e5 #/**< Receiving a request to trade */ +SMSG_TRADE_RESPONSE = 0x00e7 +SMSG_TRADE_ITEM_ADD = 0x00e9 +SMSG_TRADE_ITEM_ADD_RESPONSE = 0x01b1 #/**< Not standard eAthena! */ +SMSG_TRADE_OK = 0x00ec +SMSG_TRADE_CANCEL = 0x00ee +SMSG_TRADE_COMPLETE = 0x00f0 + +SMSG_ITEM_VISIBLE = 0x009d +SMSG_ITEM_DROPPED = 0x009e +SMSG_ITEM_REMOVE = 0x00a1 + +inventory_offset = 2 +storage_offset = 1 diff --git a/player.py b/player.py new file mode 100644 index 0000000..a63218d --- /dev/null +++ b/player.py @@ -0,0 +1,31 @@ +class Item: + pass + +class Player: + def __init__(self, name): + self.inventory = {} + self.storage = [] + self.name = name + self.id = 0 + self.sex = 0 + self.map = "" + self.x = 0 + self.y = 0 + + self.EXP_NEEDED = 0 + self.EXP = 0 + self.MONEY = 0 + self.LEVEL = 0 + self.HP = 0 + self.MaxHP = 0 + self.MP = 0 + self.MaxMP = 0 + self.WEIGHT = 0 + self.MaxWEIGHT = 0 + + def find_inventory_index(self, item_id): + for item in self.inventory: + if item > 1: + if self.inventory[item].itemId == item_id: + return item + return -10 # Not found - bug somewhere! diff --git a/tradey.py b/tradey.py new file mode 100644 index 0000000..bb83960 --- /dev/null +++ b/tradey.py @@ -0,0 +1,88 @@ +import time +from xml.etree.ElementTree import * + +class UserTree: + def __init__(self): + self.tree = ElementTree(file="data/user.xml") + self.root = self.tree.getroot() + + def add_user(self, name, stalls, al): + if self.get_user(name) == -10: + user = SubElement(self.root, "user") + user.set("name", name) + user.set("stalls", str(stalls)) + user.set("used_stalls", str(0)) + user.set("money", str(0)) + user.set("id", str(0)) + user.set("accesslevel", str(al)) + self.save() + + def get_user(self, name): + for elem in self.root: + if elem.get("name") == name: + return elem + return -10 + + def remove_user(self, name): + for elem in self.root: + if elem.get("name") == name: + self.root.remove(elem) + self.save() + return 1 + return -10 + + def save(self): + # Be sure to call save() after any changes to the tree. + self.tree = ElementTree(self.root) + self.tree.write("data/user.xml") + +class ItemTree: + def __init__(self): + self.tree = ElementTree(file="data/sale.xml") + self.root = self.tree.getroot() + self.u_id = set() + + for elem in self.root: + self.u_id.add(int(elem.get("uid"))) + + def getId(self): + id_itter = 1 + while id_itter in self.u_id: + id_itter += 1 + self.u_id.add(id_itter) + return id_itter + + def remove_id(self, uid): + # Free up used id's. + self.u_id.remove(uid) + + def add_item(self, name, item_id, amount, price): + user = SubElement(self.root, "item") + user.set("name", name) + user.set("itemId", str(item_id)) + user.set("price", str(price)) + user.set("add_time", str(time.time())) + user.set("relisted", str(0)) + user.set("amount", str(amount)) + user.set("uid", str(self.getId())) + self.save() + + def get_uid(self, uid): + for elem in self.root: + if elem.get("uid") == str(uid): + return elem + return -10 + + def remove_item_uid(self, uid): + for elem in self.root: + if elem.get("uid") == str(uid): + self.root.remove(elem) + self.remove_id(uid) + self.save() + return 1 + return -10 + + def save(self): + # Be sure to call save() after any changes to the tree. + self.tree = ElementTree(self.root) + self.tree.write("data/sale.xml") diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..3215457 --- /dev/null +++ b/utils.py @@ -0,0 +1,115 @@ +from xml.etree.ElementTree import ElementTree +from player import Item + +import struct +import time +import mutex +import threading +from net.packet_out import * + +# Process a recieved ip address. +def parse_ip(a): + return "%s.%s.%s.%s" % ((a % 256),((a >> 8) % 256),((a >> 16) % 256),((a >> 24) % 256)) + +# Remove colors from a message +def remove_colors(msg): + if len(msg) > 2: + for f in range(len(msg)-2): + while (len(msg) > f + 2) and (msg[f] == "#")\ + and (msg[f+1] == "#"): + msg = msg[0:f]+msg[f+3:] + return msg + +# Encode string - used with 4144 shop compatibility. +def encode_str(value, size): + output = '' + base = 94 + start = 33 + while value: + output += struct.pack(' 500: + item_struct = Item() + item_struct.name = item.get('name') + if item.get('weight'): + item_struct.weight = item.get('weight') + item_struct.description = item.get('description') + self.item_names[int(item.get('id'))] = item_struct + + def getItem(self, item_id): + return self.item_names[item_id] + + def findId(self, name): + for item_id in self.item_names: + if self.item_names[item_id].name == name: + return item_id + return -10 #Not found + +class ItemLog: + """ Writes all sales to a log file, for later processing.""" + def __init__(self): + self.log_file = 'logs/sale.log' + + def add_item(self, item_id, amount, price): + file_node = open(self.log_file, 'a') + file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+"\n") + file_node.close() + +class TraderState: + """ Stores information regarding a trade request""" + def __init__(self): + self.Trading = mutex.mutex() + self.item = 0 + self.money = 0 + self.complete = 0 + self.timer = 0 + + def reset(self): + self.Trading.unlock() + self.item = 0 + self.complete = 0 + self.money = 0 + self.timer = 0 + +class Broadcast: + """Send a message to the server every 5 minutes to avoid a timeout.""" + + def __init__(self): + self.mapserv = 0 + self.Active = False + self.Timer = 0 + self.shop_broadcast = threading.Thread(target=self.send_broadcast, args=()) + + def send_broadcast(self): + while self.Active: + if (time.time() - self.Timer) > 5 * 60: + self.mapserv.sendall(emote(193)) + self.Timer = time.time() + print "shop_broadcast" + else: + time.sleep(0.1) + + def start(self): + self.Active = True + self.shop_broadcast.start() + + def stop(self): + self.Active = False + self.shop_broadcast.join() -- cgit v1.2.3-70-g09d2 From 245ca375ed6212ef142b4ae55d68243fd8822410 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 21 Aug 2011 19:10:21 +0100 Subject: Fix: A mistake in the read_coord_pair packet code. --- net/packet.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/packet.py b/net/packet.py index 4442455..85a09f9 100644 --- a/net/packet.py +++ b/net/packet.py @@ -77,7 +77,7 @@ class PacketOut: tmp <<= 4 d_1 |= (tmp >> 8) % 256 d_2 = tmp % 256 - # d_2 |= direction + d_2 |= direction self.buff += chr(d_0) + chr(d_1) + chr(d_2) class PacketIn: @@ -108,15 +108,15 @@ class PacketIn: return int_value def make_word(self, low, high): - return ((low | high) << 8) + return (low | (high << 8)) def read_coord_pair(self): cdata = self.data[self.pos:self.pos + 5] - dst_x = (self.make_word(struct.unpack("> 2) % 255 - dst_y = self.make_word(struct.unpack("> 2) + dst_y = self.make_word(struct.unpack("> 6) % 255 - src_y = (self.make_word(struct.unpack("> 4) % 255 + src_x = (self.make_word(struct.unpack("> 6) + src_y = (self.make_word(struct.unpack("> 4) self.pos = self.pos + 5 return src_x, src_y, dst_x, dst_y -- cgit v1.2.3-70-g09d2 From 6f1e1b6cebaf013eb3a5c3794286c534519e5758 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 20:29:37 +0200 Subject: removing data dir and ignoring it --- .gitignore | 2 + data/items.xml | 5540 -------------------------------------------------------- data/sale.xml | 1 - data/user.xml | 1 - 4 files changed, 2 insertions(+), 5542 deletions(-) create mode 100644 .gitignore delete mode 100644 data/items.xml delete mode 100644 data/sale.xml delete mode 100644 data/user.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e67bd4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data + diff --git a/data/items.xml b/data/items.xml deleted file mode 100644 index 1656c73..0000000 --- a/data/items.xml +++ /dev/null @@ -1,5540 +0,0 @@ - - - - - - - - hairstyles/hairstyle01.xml - - - hairstyles/hairstyle02.xml - - - hairstyles/hairstyle03.xml - - - hairstyles/hairstyle04.xml - - - hairstyles/hairstyle05.xml - - - hairstyles/hairstyle06.xml - - - hairstyles/hairstyle07.xml - - - hairstyles/hairstyle08.xml - - - hairstyles/hairstyle09.xml - - - hairstyles/hairstyle10.xml - - - hairstyles/hairstyle11.xml - - - hairstyles/hairstyle12.xml - - - hairstyles/hairstyle13.xml - - - hairstyles/hairstyle14.xml - - - hairstyles/hairstyle15.xml - - - hairstyles/hairstyle16.xml - - - hairstyles/hairstyle17.xml - - - hairstyles/hairstyle18.xml - - - - - player_male_base.xml - player_female_base.xml - - - - - - - - - weapon-dagger.xml - weapons/swords/short-sword-miss1.ogg - weapons/swords/short-sword-hit1.ogg - - - weapon-bow.xml - weapons/bows/bow_shoot_1.ogg - - - weapon-scythe.xml - - - weapon-dagger.xml - weapons/swords/short-sword-miss1.ogg - weapons/swords/short-sword-hit1.ogg - - - weapon-fist.xml - - - weapon-staff.xml - - - - - - - - - - - - - - - - equipment/head/santahat.xml - - - - - - - - - - - - weapon-dagger.xml - weapons/swords/short-sword-miss1.ogg - weapons/swords/short-sword-hit1.ogg - - - weapon-dagger.xml - weapons/knives/sharpknife-miss1.ogg - - - equipment/chest/leather-male.xml|#573a26,9e7654,d3b79e,ffffff;#b96b3d,fbf5f1 - equipment/chest/leather-female.xml|#412300,603100,8d4900;#ffff00 - - - equipment/head/fancyhat.xml - - - equipment/head/minershat.xml - - - - - equipment/feet/boots-male.xml|#623a34,f0c2b4 - equipment/feet/boots-female.xml|#623a34,f0c2b4 - - - - weapon-bow.xml - weapons/bows/bow_shoot_1.ogg - - - equipment/hands/generic-male.xml|#202020,505050 - equipment/hands/generic-female.xml|#202020,505050 - - - equipment/hands/generic-male.xml|#4e2e18,c8752f - equipment/hands/generic-female.xml|#4e2e18,c8752f - - - - - - weapon-dagger.xml - - - - - - - - - equipment/head/standardheadband.xml|#563f25,99784c,d8bd86,ffffff - - - equipment/head/silkheadband.xml - - - weapon-bow.xml - weapons/bows/bow_shoot_1.ogg - - - equipment/chest/leather-male.xml|#443c21,85794a,beb590,ffffff;#824035,d6a19a - equipment/chest/leather-female.xml|#251e06,443c21,71653b,a0945e;#b6574a - - - - - - weapon-axe-blacksmith.xml - - - - - - - - - - - - - - - equipment/hands/generic-male.xml|#202020,c0c0c0,ffffff,ffffff - equipment/hands/generic-female.xml|#202020,c0c0c0,ffffff,ffffff - - - equipment/chest/tnecksweater-male.xml|#a4b2b2,ffffff - equipment/chest/tnecksweater-female.xml|#a4b2b2,ffffff - - - - - - - - weapon-dagger.xml - - - weapon-dagger.xml - - - - - - - - - - weapon-dagger.xml - - - - - - - - - equipment/legs/shorts-male.xml|#a4b2b2,ffffff - equipment/legs/shorts-female.xml|#a4b2b2,ffffff - - - - - weapon-sword-sword.xml - - - - - - - - - - - - equipment/legs/shorts-male.xml|#255367,266c84,68b0c5,ffffff - equipment/legs/shorts-female.xml|#255367,266c84,68b0c5,ffffff - - - - - - - equipment/head/pumpkinhelmet.xml - - - equipment/head/axehat.xml - - - equipment/head/piratehat.xml - - - equipment/head/goggles.xml|#787878,f7f7f7 - - - equipment/head/goggles.xml|#783c00,ff973b - - - equipment/head/circlet.xml - - - equipment/head/eyepatch.xml - - - equipment/head/bandana.xml - - - weapon-scythe.xml - - - equipment/chest/vnecksweater-male.xml|#a4b2b2,ffffff - equipment/chest/vnecksweater-female.xml|#a4b2b2,ffffff - - - equipment/chest/chainmail-male.xml - equipment/chest/chainmail-female.xml - - - equipment/chest/lightplatemail-male.xml|#ddeeff - equipment/chest/lightplatemail-female.xml|#ddeeff - - - equipment/head/tophat.xml - - - equipment/head/funkywinter.xml - - - equipment/head/mushroom.xml - - - equipment/head/shroom.xml - - - - equipment/legs/skirt.xml|#a4b2b2,ffffff - - - equipment/head/xmaself.xml - - - equipment/head/mask.xml - - - - equipment/head/warlordhelm.xml - - - equipment/head/knighthelm.xml - - - equipment/head/infantryhelm.xml - - - equipment/head/crusadehelm.xml - - - - - equipment/legs/chaps-male.xml - equipment/legs/chaps-female.xml - - - equipment/head/cowboywhite.xml - - - equipment/head/cowboyblack.xml - - - equipment/chest/lightplatemail-male.xml|#573f10,9c8226,d3c04b,ffffff - equipment/chest/lightplatemail-female.xml|#573f10,9c8226,d3c04b,ffffff - - - equipment/head/crown.xml - - - equipment/head/devcap.xml|#9999ff - - - equipment/head/devcap.xml|#9999ff - - - equipment/chest/sorcerer-robe-male.xml|#5e7480,f1ffff,ffffff;#2554c7 - equipment/chest/sorcerer-robe-female.xml|#5e7480,f1ffff,ffffff;#2554c7 - - - equipment/chest/sorcerer-robe-male.xml|#000000;#2554c7 - equipment/chest/sorcerer-robe-female.xml|#000000;#2554c7 - - - equipment/chest/robe-male.xml|#5e7480,f1ffff,ffffff - equipment/chest/robe-female.xml|#5e7480,f1ffff,ffffff - - - equipment/chest/robe-male.xml|#000000 - equipment/chest/robe-female.xml|#000000 - - - equipment/chest/robe-male.xml|#804000 - equipment/chest/robe-female.xml|#804000 - - - equipment/head/cap.xml|#d94800 - - - equipment/feet/furboots-male.xml - equipment/feet/furboots-female.xml - - - equipment/head/serf.xml - - - - equipment/chest/warlordplate-male.xml - equipment/chest/warlordplate-female.xml - - - equipment/chest/warlordplate-male.xml|#573f10,9c8226,d3c04b,ffffff - equipment/chest/warlordplate-female.xml|#573f10,9c8226,d3c04b,ffffff - - - - - - - - - - - - - - - - - - equipment/head/gradcap.xml - - - - - equipment/head/nohmask.xml - - - equipment/head/demonmask.xml - - - - - - - - - - - equipment/chest/tanktop-male.xml|#a4b2b2,ffffff - equipment/chest/tanktop-female.xml|#a4b2b2,ffffff - - - equipment/chest/shorttanktop-male.xml|#a4b2b2,ffffff - equipment/chest/shorttanktop-female.xml|#a4b2b2,ffffff - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - equipment/chest/robe-male.xml|#ffffff - equipment/chest/robe-female.xml|#ffffff - - - equipment/head/highpriest-crown.xml - - - equipment/head/monster-skull-helm.xml - - - equipment/head/deserthat.xml|#ffffff - - - equipment/head/standardheadband.xml|#a4b2b2,ffffff - - - equipment/head/gmcap.xml|#bf0e08 - - - equipment/chest/robe-male.xml|#e40a0a - equipment/chest/robe-female.xml|#e40a0a - - - - - - - equipment/legs/assassin-male.xml - equipment/legs/assassin-female.xml - - - - - equipment/feet/boots-male.xml|#212121 - equipment/feet/boots-female.xml|#212121 - - - equipment/feet/boots-male.xml|#a4b2b2,ffffff - equipment/feet/boots-female.xml|#a4b2b2,ffffff - - - - - - - - equipment/hands/generic-male.xml|#a4b2b2,ffffff - equipment/hands/generic-female.xml|#a4b2b2,ffffff - - - - - - - - - - - - equipment/head/pinkiehat.xml - - - equipment/head/fluffyhat.xml - - - - - equipment/chest/assassin-male.xml - equipment/chest/assassin-female.xml - - - equipment/hands/assassin-male.xml - equipment/hands/assassin-female.xml - - - equipment/feet/assassin-boots-male.xml - equipment/feet/assassin-boots-female.xml - - - weapon-staff.xml - - - equipment/head/paladinhelm.xml - - - equipment/head/overlordhelm.xml - - - equipment/head/desert-helmet.xml - - - - - equipment/head/sailor-hat.xml - - - equipment/head/captain-hat.xml - - - equipment/head/terranitehelm.xml - - - equipment/chest/terranite-male.xml - equipment/chest/terranite-female.xml - - - equipment/legs/terranite-male.xml - equipment/legs/terranite-female.xml - - - equipment/head/guyfawkes.xml - - - equipment/head/fairy_hat.xml - - - equipment/legs/miniskirt-male.xml|#a4b2b2,ffffff - equipment/legs/miniskirt-female.xml|#a4b2b2,ffffff - - - - - - - - - - - - equipment/head/witch-doctor-mask.xml - - - equipment/chest/forest-armor-male.xml - equipment/chest/forest-armor-female.xml - - - equipment/chest/valentine-dress.xml|#bf0e08 - - - - - - - - - - equipment/chest/leather-male.xml|#573a26,c9866b,d3b79e,ffffff;#b96b3d,fbf5f1 - equipment/chest/leather-female.xml|#412300,c9866b,8d4900;#ffff00 - - - equipment/feet/bromenalboots-male.xml - equipment/feet/bromenalboots-female.xml - - - equipment/chest/bromenalchest-male.xml|#fbf5e9 - equipment/chest/bromenalchest-female.xml|#fbf5e9 - - - equipment/hands/bromenalgloves-male.xml - equipment/hands/bromenalgloves-female.xml - - - equipment/head/bromenalhelmet.xml - - - equipment/legs/bromenallegs-male.xml - equipment/legs/bromenallegs-female.xml - - - - equipment/chest/sorcerer-robe-male.xml|#ffffff - equipment/chest/sorcerer-robe-female.xml|#ffffff - - - - equipment/head/bowler-hat-brown.xml - - - equipment/head/pinkie-helmet.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - weapon-bow.xml - weapons/bows/bow_shoot_1.ogg - - - weapon-dagger.xml - - - equipment/chest/cotton-male.xml|#a4b2b2,ffffff - equipment/chest/cotton-female.xml|#a4b2b2,ffffff - - - equipment/head/rangerhat.xml - - - equipment/head/antlerhat.xml - - - equipment/head/christmastree.xml - - - equipment/head/santabeardhat.xml - - - - - - - - - - equipment/head/bunnyears.xml - - - weapon-dagger.xml - weapons/swords/short-sword-miss1.ogg - weapons/swords/sabre-hit1.ogg - - - equipment/head/mouboohead.xml - - - equipment/head/catears.xml|#774444;#777777 - - - equipment/head/paperbag.xml - - - equipment/head/moubootaurhead.xml - - - equipment/head/parsley-earplugs.xml - - - equipment/head/skullmask.xml - - - - - - - - - - - - - - - - - - - - - - - equipment/head/snowgoggles.xml - - - - - - equipment/override/skeleton.xml - graphics/particles/wisp.particle.xml - - - - - equipment/head/heart-glasses.xml - - - - - - - - - - equipment/head/rabbit-ears.xml|#ffffff - - - equipment/head/eggshell.xml - - - - - equipment/head/operamask.xml - - - equipment/head/jestermask.xml - - - equipment/head/witch-hat.xml - - - equipment/head/goblin-mask.xml - - - - - - - - - equipment/chest/cotton-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/cotton-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/cotton-male.xml|#115511,22aa22,99dd99 - equipment/chest/cotton-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/cotton-male.xml|#222255,6666ff - equipment/chest/cotton-female.xml|#222255,6666ff - - - equipment/chest/cotton-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/cotton-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/cotton-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/cotton-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/cotton-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/cotton-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/cotton-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/cotton-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/cotton-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/cotton-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/cotton-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/cotton-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/cotton-male.xml|#104010,208020,30c030 - equipment/chest/cotton-female.xml|#104010,208020,30c030 - - - - equipment/chest/vnecksweater-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/vnecksweater-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/vnecksweater-male.xml|#115511,22aa22,99dd99 - equipment/chest/vnecksweater-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/vnecksweater-male.xml|#222255,6666ff - equipment/chest/vnecksweater-female.xml|#222255,6666ff - - - equipment/chest/vnecksweater-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/vnecksweater-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/vnecksweater-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/vnecksweater-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/vnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/vnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/vnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/vnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/vnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/vnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/vnecksweater-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/vnecksweater-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/vnecksweater-male.xml|#104010,208020,30c030 - equipment/chest/vnecksweater-female.xml|#104010,208020,30c030 - - - - equipment/chest/tnecksweater-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/tnecksweater-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/tnecksweater-male.xml|#115511,22aa22,99dd99 - equipment/chest/tnecksweater-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/tnecksweater-male.xml|#222255,6666ff - equipment/chest/tnecksweater-female.xml|#222255,6666ff - - - equipment/chest/tnecksweater-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/tnecksweater-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/tnecksweater-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/tnecksweater-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/tnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/tnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/tnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/tnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/tnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/tnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/tnecksweater-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/tnecksweater-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/tnecksweater-male.xml|#104010,208020,30c030 - equipment/chest/tnecksweater-female.xml|#104010,208020,30c030 - - - - equipment/chest/robe-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/robe-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/robe-male.xml|#115511,22aa22,99dd99 - equipment/chest/robe-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/robe-male.xml|#222255,6666ff - equipment/chest/robe-female.xml|#222255,6666ff - - - equipment/chest/robe-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/robe-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/robe-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/robe-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/robe-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/robe-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/robe-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/robe-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/robe-male.xml|#104010,208020,30c030 - equipment/chest/robe-female.xml|#104010,208020,30c030 - - - - equipment/chest/tanktop-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/tanktop-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/tanktop-male.xml|#115511,22aa22,99dd99 - equipment/chest/tanktop-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/tanktop-male.xml|#222255,6666ff - equipment/chest/tanktop-female.xml|#222255,6666ff - - - equipment/chest/tanktop-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/tanktop-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/tanktop-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/tanktop-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/tanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/tanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/tanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/tanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/tanktop-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/tanktop-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/tanktop-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/tanktop-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/tanktop-male.xml|#104010,208020,30c030 - equipment/chest/tanktop-female.xml|#104010,208020,30c030 - - - - equipment/legs/skirt.xml|#580000,a40000,c02020,ff6060 - - - equipment/legs/skirt.xml|#115511,22aa22,99dd99 - - - equipment/legs/skirt.xml|#222255,6666ff - - - equipment/legs/skirt.xml|#846211,dab333,fffb93,ffffff - - - equipment/legs/skirt.xml|#16486e,498ec5,e4f2fc - - - equipment/legs/skirt.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/legs/skirt.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/legs/skirt.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/legs/skirt.xml|#4f0a76,8010c0,d699f7 - - - equipment/legs/skirt.xml|#104010,208020,30c030 - - - - equipment/legs/shorts-male.xml|#580000,a40000,c02020,ff6060 - equipment/legs/shorts-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/legs/shorts-male.xml|#115511,22aa22,99dd99 - equipment/legs/shorts-female.xml|#115511,22aa22,99dd99 - - - equipment/legs/shorts-male.xml|#222255,6666ff - equipment/legs/shorts-female.xml|#222255,6666ff - - - equipment/legs/shorts-male.xml|#846211,dab333,fffb93,ffffff - equipment/legs/shorts-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/legs/shorts-male.xml|#16486e,498ec5,e4f2fc - equipment/legs/shorts-female.xml|#16486e,498ec5,e4f2fc - - - equipment/legs/shorts-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/legs/shorts-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/legs/shorts-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/legs/shorts-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/legs/shorts-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/legs/shorts-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/legs/shorts-male.xml|#520a7b,8c23c7,ca87ef - equipment/legs/shorts-female.xml|#520a7b,8c23c7,ca87ef - - - equipment/legs/shorts-male.xml|#104010,208020,30c030 - equipment/legs/shorts-female.xml|#104010,208020,30c030 - - - - equipment/chest/shorttanktop-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/shorttanktop-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/shorttanktop-male.xml|#115511,22aa22,99dd99 - equipment/chest/shorttanktop-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/shorttanktop-male.xml|#222255,6666ff - equipment/chest/shorttanktop-female.xml|#222255,6666ff - - - equipment/chest/shorttanktop-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/shorttanktop-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/shorttanktop-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/shorttanktop-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/shorttanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/shorttanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/shorttanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/shorttanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/shorttanktop-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/shorttanktop-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/shorttanktop-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/shorttanktop-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/shorttanktop-male.xml|#104010,208020,30c030 - equipment/chest/shorttanktop-female.xml|#104010,208020,30c030 - - - - equipment/head/deserthat.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/deserthat.xml|#115511,22aa22,99dd99 - - - equipment/head/deserthat.xml|#222255,6666ff - - - equipment/head/deserthat.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/deserthat.xml|#16486e,498ec5,e4f2fc - - - equipment/head/deserthat.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/deserthat.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/deserthat.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/deserthat.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/deserthat.xml|#104010,208020,30c030 - - - - equipment/head/standardheadband.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/standardheadband.xml|#115511,22aa22,99dd99 - - - equipment/head/standardheadband.xml|#222255,6666ff - - - equipment/head/standardheadband.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/standardheadband.xml|#16486e,498ec5,e4f2fc - - - equipment/head/standardheadband.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/standardheadband.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/standardheadband.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/standardheadband.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/standardheadband.xml|#104010,208020,30c030 - - - - equipment/feet/boots-male.xml|#580000,a40000,c02020,ff6060 - equipment/feet/boots-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/feet/boots-male.xml|#115511,22aa22,99dd99 - equipment/feet/boots-female.xml|#115511,22aa22,99dd99 - - - equipment/feet/boots-male.xml|#222255,6666ff - equipment/feet/boots-female.xml|#222255,6666ff - - - equipment/feet/boots-male.xml|#846211,dab333,fffb93,ffffff - equipment/feet/boots-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/feet/boots-male.xml|#16486e,498ec5,e4f2fc - equipment/feet/boots-female.xml|#16486e,498ec5,e4f2fc - - - equipment/feet/boots-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/feet/boots-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/feet/boots-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/feet/boots-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/feet/boots-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/feet/boots-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/feet/boots-male.xml|#4f0a76,8010c0,d699f7 - equipment/feet/boots-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/feet/boots-male.xml|#104010,208020,30c030 - equipment/feet/boots-female.xml|#104010,208020,30c030 - - - - equipment/hands/generic-male.xml|#580000,a40000,c02020,ff6060 - equipment/hands/generic-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/hands/generic-male.xml|#115511,22aa22,99dd99 - equipment/hands/generic-female.xml|#115511,22aa22,99dd99 - - - equipment/hands/generic-male.xml|#222255,6666ff - equipment/hands/generic-female.xml|#222255,6666ff - - - equipment/hands/generic-male.xml|#846211,dab333,fffb93,ffffff - equipment/hands/generic-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/hands/generic-male.xml|#16486e,498ec5,e4f2fc - equipment/hands/generic-female.xml|#16486e,498ec5,e4f2fc - - - equipment/hands/generic-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/hands/generic-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/hands/generic-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/hands/generic-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/hands/generic-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/hands/generic-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/hands/generic-male.xml|#4f0a76,8010c0,d699f7 - equipment/hands/generic-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/hands/generic-male.xml|#104010,208020,30c030 - equipment/hands/generic-female.xml|#104010,208020,30c030 - - - - equipment/legs/miniskirt-male.xml|#580000,a40000,c02020,ff6060 - equipment/legs/miniskirt-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/legs/miniskirt-male.xml|#115511,22aa22,99dd99 - equipment/legs/miniskirt-female.xml|#115511,22aa22,99dd99 - - - equipment/legs/miniskirt-male.xml|#222255,6666ff - equipment/legs/miniskirt-female.xml|#222255,6666ff - - - equipment/legs/miniskirt-male.xml|#846211,dab333,fffb93,ffffff - equipment/legs/miniskirt-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/legs/miniskirt-male.xml|#16486e,498ec5,e4f2fc - equipment/legs/miniskirt-female.xml|#16486e,498ec5,e4f2fc - - - equipment/legs/miniskirt-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/legs/miniskirt-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/legs/miniskirt-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/legs/miniskirt-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/legs/miniskirt-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/legs/miniskirt-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/legs/miniskirt-male.xml|#4f0a76,8010c0,d699f7 - equipment/legs/miniskirt-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/legs/miniskirt-male.xml|#104010,208020,30c030 - equipment/legs/miniskirt-female.xml|#104010,208020,30c030 - - - - - - equipment/head/rabbit-ears.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/rabbit-ears.xml|#115511,22aa22,99dd99 - - - equipment/head/rabbit-ears.xml|#222255,6666ff - - - equipment/head/rabbit-ears.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/rabbit-ears.xml|#16486e,498ec5,e4f2fc - - - equipment/head/rabbit-ears.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/rabbit-ears.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/rabbit-ears.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/rabbit-ears.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/rabbit-ears.xml|#104010,208020,30c030 - - - - equipment/head/wizard-hat.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/wizard-hat.xml|#115511,22aa22,99dd99 - - - equipment/head/wizard-hat.xml|#222255,6666ff - - - equipment/head/wizard-hat.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/wizard-hat.xml|#16486e,498ec5,e4f2fc - - - equipment/head/wizard-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/wizard-hat.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/wizard-hat.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/wizard-hat.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/wizard-hat.xml|#104010,208020,30c030 - - - - equipment/head/bowler-hat.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/bowler-hat.xml|#115511,22aa22,99dd99 - - - equipment/head/bowler-hat.xml|#222255,6666ff - - - equipment/head/bowler-hat.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/bowler-hat.xml|#16486e,498ec5,e4f2fc - - - equipment/head/bowler-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/bowler-hat.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/bowler-hat.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/bowler-hat.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/bowler-hat.xml|#104010,208020,30c030 - - - - equipment/chest/sorcerer-robe-male.xml|#580000,a40000,c02020,ff6060 - equipment/chest/sorcerer-robe-female.xml|#580000,a40000,c02020,ff6060 - - - equipment/chest/sorcerer-robe-male.xml|#115511,22aa22,99dd99 - equipment/chest/sorcerer-robe-female.xml|#115511,22aa22,99dd99 - - - equipment/chest/sorcerer-robe-male.xml|#222255,6666ff - equipment/chest/sorcerer-robe-female.xml|#222255,6666ff - - - equipment/chest/sorcerer-robe-male.xml|#846211,dab333,fffb93,ffffff - equipment/chest/sorcerer-robe-female.xml|#846211,dab333,fffb93,ffffff - - - equipment/chest/sorcerer-robe-male.xml|#16486e,498ec5,e4f2fc - equipment/chest/sorcerer-robe-female.xml|#16486e,498ec5,e4f2fc - - - equipment/chest/sorcerer-robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff - equipment/chest/sorcerer-robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/chest/sorcerer-robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa - equipment/chest/sorcerer-robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/chest/sorcerer-robe-male.xml|#80280f,b04810,ef681f,ffb830 - equipment/chest/sorcerer-robe-female.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/chest/sorcerer-robe-male.xml|#4f0a76,8010c0,d699f7 - equipment/chest/sorcerer-robe-female.xml|#4f0a76,8010c0,d699f7 - - - equipment/chest/sorcerer-robe-male.xml|#104010,208020,30c030 - equipment/chest/sorcerer-robe-female.xml|#104010,208020,30c030 - - - - equipment/head/bowler-hat-brown.xml|#580000,a40000,c02020,ff6060 - - - equipment/head/bowler-hat-brown.xml|#115511,22aa22,99dd99 - - - equipment/head/bowler-hat-brown.xml|#222255,6666ff - - - equipment/head/bowler-hat-brown.xml|#846211,dab333,fffb93,ffffff - - - equipment/head/bowler-hat-brown.xml|#16486e,498ec5,e4f2fc - - - equipment/head/bowler-hat-brown.xml|#56002f,930050,fe70bd,feb7de,ffffff - - - equipment/head/bowler-hat-brown.xml|#111111,222222,333333,444444,555555,aaaaaa - - - equipment/head/bowler-hat-brown.xml|#80280f,b04810,ef681f,ffb830 - - - equipment/head/bowler-hat-brown.xml|#4f0a76,8010c0,d699f7 - - - equipment/head/bowler-hat-brown.xml|#104010,208020,30c030 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - equipment/head/candlehelmet.xml - - - - - - - - - equipment/head/yeti-mask.xml - - - equipment/head/wizard-hat.xml - - - - equipment/head/bowler-hat.xml - - - equipment/head/monocle.xml - - diff --git a/data/sale.xml b/data/sale.xml deleted file mode 100644 index 374d3f4..0000000 --- a/data/sale.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/data/user.xml b/data/user.xml deleted file mode 100644 index bc58f62..0000000 --- a/data/user.xml +++ /dev/null @@ -1 +0,0 @@ - -- cgit v1.2.3-70-g09d2 From d60960b746b398ef63090c4e2cc89e6fac873ddd Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 20:35:39 +0200 Subject: correct git ignore file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9e67bd4..6dbccb1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -data +data/ -- cgit v1.2.3-70-g09d2 From e15f61bfc5456b58ac099bff61646df012f468a0 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 20:48:06 +0200 Subject: Adding Copyright note to main.py --- main.py | 109 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/main.py b/main.py index 3a217cd..ddf4c24 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,7 @@ -""" This package implements an Automated Market Bot for "The Mana World" a 2D MMORPG. +""" + Copyright 2011, Dipesh Amin + + This package implements an Automated Market Bot for "The Mana World" a 2D MMORPG. - Currently permissions are defined as: -1 (blocked), 0 (normal user), 5 (seller), 20 (admin). - An item will only be listed for a period of one week, and can be relisted @@ -37,7 +40,7 @@ def process_whisper(nick, msg, mapserv): msg = filter(lambda x: x in string.printable, msg) user = user_tree.get_user(nick) broken_string = msg.split() - + if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) @@ -49,7 +52,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "The following items are on sale:")) else: mapserv.sendall(whisper(nick, "No items for sale.")) - + for elem in sale_tree.root: if time.time() - float(elem.get('add_time')) < 604800: # Check if an items time is up. msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ @@ -81,7 +84,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Item not found. Please check and try again.")) else: mapserv.sendall(whisper(nick, "Syntax incorrect")) - + elif msg == "!info": # Send information related to a player. if user == -10: @@ -105,7 +108,7 @@ def process_whisper(nick, msg, mapserv): stall_msg = "You have " + str(int(user.get('stalls')) - int(user.get('used_stalls'))) + " free slots." mapserv.sendall(whisper(nick, stall_msg)) - elif broken_string[0] == "!help": + elif broken_string[0] == "!help": # Sends help information if len(broken_string) == 1: mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) @@ -141,7 +144,7 @@ def process_whisper(nick, msg, mapserv): if user == -10: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return - + amount = int(user.get('money')) if amount == 0: mapserv.sendall(whisper(nick, "You have no money to collect.")) @@ -167,7 +170,7 @@ def process_whisper(nick, msg, mapserv): items_found = False item = " ".join(broken_string[1:]) # could be an id or an item name - + if item.isdigit(): # an id for elem in sale_tree.root: if ((time.time() - float(elem.get('add_time'))) < 604800) \ @@ -175,7 +178,7 @@ def process_whisper(nick, msg, mapserv): msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" mapserv.sendall(whisper(nick, msg)) - items_found = True + items_found = True else: # an item name for elem in sale_tree.root: if ((time.time() - float(elem.get('add_time'))) < 604800) \ @@ -196,7 +199,7 @@ def process_whisper(nick, msg, mapserv): if int(user.get("accesslevel")) != 20: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return - + data = '' for user in user_tree.root: @@ -209,7 +212,7 @@ def process_whisper(nick, msg, mapserv): # Format ManaMarket (20) 2/5 100000gp, if len(data) > 400: - mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) data = '' mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) @@ -255,7 +258,7 @@ def process_whisper(nick, msg, mapserv): if len(broken_string) < 3: mapserv.sendall(whisper(nick, "Syntax incorrect.")) return - + if (broken_string[1][0] == '-' and broken_string[1][1:].isdigit()) or broken_string[1].isdigit(): accesslevel = int(broken_string[1]) name = " ".join(broken_string[2:]) @@ -265,17 +268,17 @@ def process_whisper(nick, msg, mapserv): if user_info == -10: mapserv.sendall(whisper(nick, "User not found, check and try again.")) return - + if int(user_info.get('accesslevel')) < int(user.get("accesslevel")) and accesslevel <= int(user.get("accesslevel")): user_tree.get_user(name).set('accesslevel', str(accesslevel)) mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) user_tree.save() else: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - + elif broken_string[0] == "!adduser": # A command to give a user access to the bot - !adduser . @@ -312,7 +315,7 @@ def process_whisper(nick, msg, mapserv): if int(user.get("accesslevel")) < 5: mapserv.sendall(whisper(nick, "You are unable to add items.")) return - + if int(user.get("used_stalls")) >= int(user.get("stalls")): mapserv.sendall(whisper(nick, "You have no free slots. You may remove an item or wait for something to be sold.")) return @@ -320,7 +323,7 @@ def process_whisper(nick, msg, mapserv): if broken_string[1].isdigit() and broken_string[2].isdigit(): amount = int(broken_string[1]) price = int(broken_string[2]) - item_name = " ".join(broken_string[3:]) + item_name = " ".join(broken_string[3:]) item_id = ItemDB.findId(item_name) if item_id == -10: mapserv.sendall(whisper(nick, "Item not found, check spelling.")) @@ -333,7 +336,7 @@ def process_whisper(nick, msg, mapserv): item.amount = amount item.price = price trader_state.item = item - + if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return @@ -357,7 +360,7 @@ def process_whisper(nick, msg, mapserv): amount = int(broken_string[1]) uid = int(broken_string[2]) item_info = sale_tree.get_uid(uid) - + if item_info == -10: mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) return @@ -385,7 +388,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "That will be " + str(item.price * item.amount) + "gp.")) else: mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) - trader_state.reset() + trader_state.reset() else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -408,7 +411,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "User Removed.")) elif check == -10: mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) - + elif broken_string[0] == "!relist": # Relist an item which has expired - !relist . if user == -10 or len(broken_string) != 2: @@ -430,9 +433,9 @@ def process_whisper(nick, msg, mapserv): if item_info.get('name') != nick: mapserv.sendall(whisper(nick, "That doesn't belong to you!")) return - + time_relisted = int(item_info.get('relisted')) - + if int(item_info.get('relisted')) < 3: sale_tree.get_uid(uid).set('add_time', str(time.time())) sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) @@ -443,7 +446,7 @@ def process_whisper(nick, msg, mapserv): return else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - + elif broken_string[0] == "!getback": # Trade the player back uid, remove from sale_items if trade successful - !getback . if user == -10 or len(broken_string) != 2: @@ -490,7 +493,7 @@ def main(): logging.basicConfig(filename='logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') logging.info("Bot Started.") - account = sys.argv[1] + account = sys.argv[1] password = sys.argv[2] character = sys.argv[3] @@ -501,7 +504,7 @@ def main(): login_packet = PacketOut(0x0064) login_packet.write_int32(0) login_packet.write_string(account, 24) - login_packet.write_string(password, 24) + login_packet.write_string(password, 24) login_packet.write_int8(0x03); login.sendall(str(login_packet)) @@ -517,13 +520,13 @@ def main(): break pb.feed(data) for packet in pb: - if packet.is_type(SMSG_LOGIN_DATA): # login succeeded + if packet.is_type(SMSG_LOGIN_DATA): # login succeeded packet.skip(2) - id1 = packet.read_int32() + id1 = packet.read_int32() accid = packet.read_int32() id2 = packet.read_int32() packet.skip(30) - player_node.sex = packet.read_int8() + player_node.sex = packet.read_int8() charip = utils.parse_ip(packet.read_int32()) charport = packet.read_int16() login.close() @@ -584,7 +587,7 @@ def main(): char_select_packet = PacketOut(CMSG_CHAR_SELECT) char_select_packet.write_int8(int(character)) - char.sendall(str(char_select_packet)) + char.sendall(str(char_select_packet)) elif packet.is_type(SMSG_CHAR_MAP_INFO): player_node.id = packet.read_int32() @@ -627,7 +630,7 @@ def main(): logging.info("Trade Cancelled - Timeout.") trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - + for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected logging.info("Map login success.") @@ -665,7 +668,7 @@ def main(): packet.read_int32() coord_data = packet.read_coord_pair() player_node.x = coord_data[2] - player_node.y = coord_data[3] + player_node.y = coord_data[3] elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): stat_type = packet.read_int16() @@ -680,7 +683,7 @@ def main(): player_node.MaxMP = value elif stat_type == 0x000b: player_node.LEVEL = value - print "Level changed: %s" % value + print "Level changed: %s" % value elif stat_type == 0x0018: print "Weight changed from %s/%s to %s/%s" % (player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) logging.info("Weight changed from %s/%s to %s/%s", player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) @@ -701,18 +704,18 @@ def main(): elif stat_type == 0x0016: player_node.EXP_NEEDED = value print "Exp Needed: %s" % player_node.EXP_NEEDED - + elif packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_BEING_VISIBLE)\ or packet.is_type(SMSG_PLAYER_MOVE) or packet.is_type(SMSG_PLAYER_UPDATE_1)\ or packet.is_type(SMSG_PLAYER_UPDATE_2): being_id = packet.read_int32() packet.skip(8) - job = packet.read_int16() - if being_id not in beingManager.container: + job = packet.read_int16() + if being_id not in beingManager.container: if job == 0 and id >= 110000000 and (packet.is_type(SMSG_BEING_MOVE)\ or packet.is_type(SMSG_BEING_VISIBLE)): continue - # Add the being to the BeingManager, and request name. + # Add the being to the BeingManager, and request name. beingManager.container[being_id] = Being(being_id, job) requestName = PacketOut(0x0094) requestName.write_int32(being_id) @@ -724,13 +727,13 @@ def main(): packet.read_int32() packet.skip(22) - + if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): coord_data = packet.read_coord_pair() beingManager.container[being_id].dst_x = coord_data[2] beingManager.container[being_id].dst_y = coord_data[3] else: - coord_data = packet.read_coord_dir() + coord_data = packet.read_coord_dir() beingManager.container[being_id].x = coord_data[0] beingManager.container[being_id].y = coord_data[1] beingManager.container[being_id].direction = coord_data[2] @@ -744,14 +747,14 @@ def main(): being_id = packet.read_int32() if being_id in beingManager.container: del beingManager.container[being_id] - + elif packet.is_type(SMSG_PLAYER_WARP): player_node.map = packet.read_string(16) player_node.x = packet.read_int16() player_node.y = packet.read_int16() logging.info("Player warped.") mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) - + elif packet.is_type(SMSG_BEING_ACTION): src_being = packet.read_int32() dst_being = packet.read_int32() @@ -764,12 +767,12 @@ def main(): if action_type == 0: # Damage beingManager.container[src_being].action = "attack" beingManager.container[src_being].target = dst_being - + elif action_type == 0x02: # Sit beingManager.container[src_being].action = "sit" - + elif action_type == 0x03: # Stand up - beingManager.container[src_being].action = "stand" + beingManager.container[src_being].action = "stand" elif packet.is_type(SMSG_PLAYER_INVENTORY_ADD): item = Item() @@ -840,7 +843,7 @@ def main(): print "Name: %s, Id: %s, Index: %s, Amount: %s." % \ (ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) - + elif packet.is_type(SMSG_TRADE_REQUEST): print "SMSG_TRADE_REQUEST" name = packet.read_string(24) @@ -870,7 +873,7 @@ def main(): if trader_state.item.price == 0: # getback mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) trader_state.complete = 1 - + elif trader_state.money: # money amount = int(user_tree.get_user(trader_state.money).get('money')) mapserv.sendall(trade_add_item(0-inventory_offset, amount)) @@ -910,8 +913,8 @@ def main(): elif trader_state.money: # money mapserv.sendall(whisper(trader_state.money, "Don't give me your itenz.")) - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + logging.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) # Note item_id = 0 is money @@ -940,7 +943,7 @@ def main(): elif response == 1: logging.info("Trade item add response: Failed - player overweight.") - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "You are carrying too much weight. Unload and try again.")) elif response == 2: @@ -956,7 +959,7 @@ def main(): logging.info("Trade OK: Self.") else: if trader_state.complete: - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) else: mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) @@ -987,7 +990,7 @@ def main(): sale_tree.remove_item_uid(trader_state.item.uid) current_money = int(user_tree.get_user(seller).get("money")) - user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) + user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) if trader_state.item.price * trader_state.item.amount != 0: ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) @@ -1003,10 +1006,10 @@ def main(): else: pass #print "Unhandled Packet: %s" % hex(packet.get_type()) - + # On Disconnect/Exit shop_broadcaster.stop() - mapserv.close() + mapserv.close() if __name__ == '__main__': main() -- cgit v1.2.3-70-g09d2 From fba20e9689b6a0407b193fb3c708be45ca68ac71 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 21 Aug 2011 19:49:05 +0100 Subject: Change the directory logs are stored in. --- main.py | 2 +- utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index ddf4c24..d3824ff 100644 --- a/main.py +++ b/main.py @@ -490,7 +490,7 @@ def process_whisper(nick, msg, mapserv): trader_state.reset() def main(): - logging.basicConfig(filename='logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') + logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') logging.info("Bot Started.") account = sys.argv[1] diff --git a/utils.py b/utils.py index 3215457..8e7f839 100644 --- a/utils.py +++ b/utils.py @@ -65,7 +65,7 @@ class ItemDB: class ItemLog: """ Writes all sales to a log file, for later processing.""" def __init__(self): - self.log_file = 'logs/sale.log' + self.log_file = 'data/logs/sale.log' def add_item(self, item_id, amount, price): file_node = open(self.log_file, 'a') -- cgit v1.2.3-70-g09d2 From 8cbb45acaa00150a831d804cf08a967b30a4c7f8 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 21 Aug 2011 20:03:58 +0100 Subject: Add config.py to gitignore. --- .gitignore | 2 +- config.py.template | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 config.py.template diff --git a/.gitignore b/.gitignore index 6dbccb1..357f8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ data/ - +config.py diff --git a/config.py.template b/config.py.template new file mode 100644 index 0000000..068d432 --- /dev/null +++ b/config.py.template @@ -0,0 +1,6 @@ +#server = "server.themanaworld.org" +server = "caliban.homeip.net" +port = 6901 +account = "" +password = "" +character = 0 #slot character is in, 0 for first, 1 for second, 2 for third -- cgit v1.2.3-70-g09d2 From 16cff2426df9bbad4682fa6fe9fd2808cd009e93 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:06:02 +0200 Subject: Remove tabs by spaces and remove config file --- being.py | 24 +- config.py | 6 - main.py | 1348 ++++++++++++++++++++++++++++++------------------------------- player.py | 44 +- tradey.py | 108 ++--- utils.py | 86 ++-- 6 files changed, 805 insertions(+), 811 deletions(-) delete mode 100644 config.py diff --git a/being.py b/being.py index 9c51a2b..52a2e1b 100644 --- a/being.py +++ b/being.py @@ -10,21 +10,21 @@ def job_type(job): class BeingManager: def __init__(self): - self.container = {} + self.container = {} def findId(self, name): - for i in self.container: - if self.container[i].name == name: - return i - return -10 + for i in self.container: + if self.container[i].name == name: + return i + return -10 class Being: def __init__(self, being_id, job): self.id = being_id - self.name = "" - self.x = 0 - self.y = 0 - self.action = "" - self.job = job - self.target = 0 - self.type = job_type(job) + self.name = "" + self.x = 0 + self.y = 0 + self.action = "" + self.job = job + self.target = 0 + self.type = job_type(job) diff --git a/config.py b/config.py deleted file mode 100644 index 068d432..0000000 --- a/config.py +++ /dev/null @@ -1,6 +0,0 @@ -#server = "server.themanaworld.org" -server = "caliban.homeip.net" -port = 6901 -account = "" -password = "" -character = 0 #slot character is in, 0 for first, 1 for second, 2 for third diff --git a/main.py b/main.py index d3824ff..41b428d 100644 --- a/main.py +++ b/main.py @@ -19,7 +19,7 @@ import time import string from being import * -from config import * +from data.config import * from net.packet import * from net.protocol import * from net.packet_out import * @@ -43,451 +43,451 @@ def process_whisper(nick, msg, mapserv): if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. - mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) - return + mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) + return if msg == "!list": - # Sends the list of items for sale. - if len(sale_tree.root) != 0: - mapserv.sendall(whisper(nick, "The following items are on sale:")) - else: - mapserv.sendall(whisper(nick, "No items for sale.")) - - for elem in sale_tree.root: - if time.time() - float(elem.get('add_time')) < 604800: # Check if an items time is up. - msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ - elem.get("itemId") + "|" + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" - mapserv.sendall(whisper(nick, msg)) + # Sends the list of items for sale. + if len(sale_tree.root) != 0: + mapserv.sendall(whisper(nick, "The following items are on sale:")) + else: + mapserv.sendall(whisper(nick, "No items for sale.")) + + for elem in sale_tree.root: + if time.time() - float(elem.get('add_time')) < 604800: # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ + elem.get("itemId") + "|" + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) elif broken_string[0] == '!selllist': - # Support for 4144's shop (Sell list) + # Support for 4144's shop (Sell list) data = '\302\202B1' - for elem in sale_tree.root: - data += utils.encode_str(int(elem.get("itemId")), 2) + for elem in sale_tree.root: + data += utils.encode_str(int(elem.get("itemId")), 2) data += utils.encode_str(int(elem.get("price")), 4) - data += utils.encode_str(int(elem.get("amount")), 3) - mapserv.sendall(whisper(nick, data)) + data += utils.encode_str(int(elem.get("amount")), 3) + mapserv.sendall(whisper(nick, data)) elif broken_string[0] == '!buyitem': - # 4144 buy command - if len(broken_string) == 4: - if broken_string[1].isdigit() and broken_string[2].isdigit() and broken_string[3].isdigit(): - # Traditional 4144 shop. - item_id = int(broken_string[1]) - price = int(broken_string[2]) - amount = int(broken_string[3]) - for elem in sale_tree.root: + # 4144 buy command + if len(broken_string) == 4: + if broken_string[1].isdigit() and broken_string[2].isdigit() and broken_string[3].isdigit(): + # Traditional 4144 shop. + item_id = int(broken_string[1]) + price = int(broken_string[2]) + amount = int(broken_string[3]) + for elem in sale_tree.root: if int(elem.get('amount')) >= amount and int(elem.get('price')) == price and int(elem.get('itemId')) == item_id: - process_whisper(nick, '!buy ' + str(amount) + " " + elem.get('uid'), mapserv) - return - mapserv.sendall(whisper(nick, "Item not found. Please check and try again.")) - else: - mapserv.sendall(whisper(nick, "Syntax incorrect")) + process_whisper(nick, '!buy ' + str(amount) + " " + elem.get('uid'), mapserv) + return + mapserv.sendall(whisper(nick, "Item not found. Please check and try again.")) + else: + mapserv.sendall(whisper(nick, "Syntax incorrect")) elif msg == "!info": # Send information related to a player. - if user == -10: - mapserv.sendall(whisper(nick, "Your current access level is 0.")) - elif int(user.get('accesslevel')) > 0: - mapserv.sendall(whisper(nick, "Your current access level is " + user.get('accesslevel') + ".")) - mapserv.sendall(whisper(nick, "Your have the following items for sale:")) - for elem in sale_tree.root: - if elem.get('name') == nick: - if time.time() - float(elem.get('add_time')) > 604800: - msg = "[expired] [" - else: - msg = "[selling] [" - - msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ - ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" - mapserv.sendall(whisper(nick, msg)) - - money = int(user.get('money')) - mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) - stall_msg = "You have " + str(int(user.get('stalls')) - int(user.get('used_stalls'))) + " free slots." - mapserv.sendall(whisper(nick, stall_msg)) + if user == -10: + mapserv.sendall(whisper(nick, "Your current access level is 0.")) + elif int(user.get('accesslevel')) > 0: + mapserv.sendall(whisper(nick, "Your current access level is " + user.get('accesslevel') + ".")) + mapserv.sendall(whisper(nick, "Your have the following items for sale:")) + for elem in sale_tree.root: + if elem.get('name') == nick: + if time.time() - float(elem.get('add_time')) > 604800: + msg = "[expired] [" + else: + msg = "[selling] [" + + msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + + money = int(user.get('money')) + mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) + stall_msg = "You have " + str(int(user.get('stalls')) - int(user.get('used_stalls'))) + " free slots." + mapserv.sendall(whisper(nick, stall_msg)) elif broken_string[0] == "!help": - # Sends help information - if len(broken_string) == 1: + # Sends help information + if len(broken_string) == 1: mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) - mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) - mapserv.sendall(whisper(nick, "For a detailed description of each command, type !help e.g. !help !buy")) - mapserv.sendall(whisper(nick, "For example:- to purchase an item shown in the list as:")) - mapserv.sendall(whisper(nick, "[selling] [6] 5 [@@640|Iron Ore@@] for 1000gp each")) - mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) - mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) - - elif len(broken_string) == 2: - if broken_string[1] == '!buy': - mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) - elif broken_string[1] == '!list': - mapserv.sendall(whisper(nick, "!list - Displays a list of all items for sale.")) - elif broken_string[1] == '!find': - mapserv.sendall(whisper(nick, "!find or - Simple search to locate an item.")) - elif broken_string[1] == '!buy': - mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) - elif broken_string[1] == '!add': - mapserv.sendall(whisper(nick, "!add - Add an item to the sell list (requires that you have an account).")) - elif broken_string[1] == '!money': - mapserv.sendall(whisper(nick, "!money - Allows you to collect money for any sales made on your behalf.")) - elif broken_string[1] == '!relist': - mapserv.sendall(whisper(nick, "!relist - Allows you to relist an item which has expired.")) - elif broken_string[1] == '!info': - mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) - elif broken_string[1] == '!getback': - mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) + mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) + mapserv.sendall(whisper(nick, "For a detailed description of each command, type !help e.g. !help !buy")) + mapserv.sendall(whisper(nick, "For example:- to purchase an item shown in the list as:")) + mapserv.sendall(whisper(nick, "[selling] [6] 5 [@@640|Iron Ore@@] for 1000gp each")) + mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) + mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) + + elif len(broken_string) == 2: + if broken_string[1] == '!buy': + mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) + elif broken_string[1] == '!list': + mapserv.sendall(whisper(nick, "!list - Displays a list of all items for sale.")) + elif broken_string[1] == '!find': + mapserv.sendall(whisper(nick, "!find or - Simple search to locate an item.")) + elif broken_string[1] == '!buy': + mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) + elif broken_string[1] == '!add': + mapserv.sendall(whisper(nick, "!add - Add an item to the sell list (requires that you have an account).")) + elif broken_string[1] == '!money': + mapserv.sendall(whisper(nick, "!money - Allows you to collect money for any sales made on your behalf.")) + elif broken_string[1] == '!relist': + mapserv.sendall(whisper(nick, "!relist - Allows you to relist an item which has expired.")) + elif broken_string[1] == '!info': + mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) + elif broken_string[1] == '!getback': + mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) elif msg == "!money": - # Trades any money earned through item sales. - if user == -10: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return - - amount = int(user.get('money')) - if amount == 0: - mapserv.sendall(whisper(nick, "You have no money to collect.")) - else: - trader_state.money = nick - if not trader_state.Trading.testandset(): - mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) - return + # Trades any money earned through item sales. + if user == -10: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + amount = int(user.get('money')) + if amount == 0: + mapserv.sendall(whisper(nick, "You have no money to collect.")) + else: + trader_state.money = nick + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return player_id = beingManager.findId(nick) - if player_id != -10: - mapserv.sendall(trade_request(player_id)) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() - else: - mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) - trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() elif broken_string[0] == "!find": - # Returns a list of items, with the corresponding Item Id - !find or . - if len(broken_string) < 2: + # Returns a list of items, with the corresponding Item Id - !find or . + if len(broken_string) < 2: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return + return - items_found = False - item = " ".join(broken_string[1:]) # could be an id or an item name + items_found = False + item = " ".join(broken_string[1:]) # could be an id or an item name - if item.isdigit(): # an id - for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < 604800) \ - and int(elem.get("itemId")) == int(item): # Check if an items time is up. - msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + if item.isdigit(): # an id + for elem in sale_tree.root: + if ((time.time() - float(elem.get('add_time'))) < 604800) \ + and int(elem.get("itemId")) == int(item): # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" - mapserv.sendall(whisper(nick, msg)) - items_found = True - else: # an item name - for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < 604800) \ - and item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): # Check if an items time is up. - msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + mapserv.sendall(whisper(nick, msg)) + items_found = True + else: # an item name + for elem in sale_tree.root: + if ((time.time() - float(elem.get('add_time'))) < 604800) \ + and item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): # Check if an items time is up. + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" - mapserv.sendall(whisper(nick, msg)) - items_found = True + mapserv.sendall(whisper(nick, msg)) + items_found = True - if not items_found: - mapserv.sendall(whisper(nick, "Item not found.")) + if not items_found: + mapserv.sendall(whisper(nick, "Item not found.")) elif msg == '!listusers': - # Admin command - shows a list of all user. + # Admin command - shows a list of all user. if user == -10: - return + return if int(user.get("accesslevel")) != 20: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return - data = '' + data = '' - for user in user_tree.root: + for user in user_tree.root: name = user.get('name') accesslevel = user.get('accesslevel') - slots = user.get('stalls') - used_slots = user.get('used_stalls') - money = user.get('money') - data += name+" ("+accesslevel+") "+used_slots+"/"+slots+" "+money+'gp, ' - # Format ManaMarket (20) 2/5 100000gp, + slots = user.get('stalls') + used_slots = user.get('used_stalls') + money = user.get('money') + data += name+" ("+accesslevel+") "+used_slots+"/"+slots+" "+money+'gp, ' + # Format ManaMarket (20) 2/5 100000gp, - if len(data) > 400: - mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) - data = '' + if len(data) > 400: + mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + data = '' mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) elif broken_string[0] == '!setslots': - # Change the number of slots a user has - !setslots + # Change the number of slots a user has - !setslots if user == -10: - return + return if int(user.get("accesslevel")) != 20: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return - if len(broken_string) < 3: + if len(broken_string) < 3: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return + return - if broken_string[1].isdigit(): - slot = int(broken_string[1]) - name = " ".join(broken_string[2:]) + if broken_string[1].isdigit(): + slot = int(broken_string[1]) + name = " ".join(broken_string[2:]) - user_info = user_tree.get_user(name) + user_info = user_tree.get_user(name) - if user_info == -10: - mapserv.sendall(whisper(nick, "User not found, check and try again.")) - return + if user_info == -10: + mapserv.sendall(whisper(nick, "User not found, check and try again.")) + return - user_tree.get_user(name).set('stalls', str(slot)) - mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) - user_tree.save() - else: + user_tree.get_user(name).set('stalls', str(slot)) + mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) + user_tree.save() + else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == '!setaccess': - # Change someones access level - !setaccess + # Change someones access level - !setaccess if user == -10: - return + return if int(user.get("accesslevel")) != 20: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return - if len(broken_string) < 3: + if len(broken_string) < 3: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return + return - if (broken_string[1][0] == '-' and broken_string[1][1:].isdigit()) or broken_string[1].isdigit(): - accesslevel = int(broken_string[1]) - name = " ".join(broken_string[2:]) + if (broken_string[1][0] == '-' and broken_string[1][1:].isdigit()) or broken_string[1].isdigit(): + accesslevel = int(broken_string[1]) + name = " ".join(broken_string[2:]) - user_info = user_tree.get_user(name) + user_info = user_tree.get_user(name) - if user_info == -10: - mapserv.sendall(whisper(nick, "User not found, check and try again.")) - return + if user_info == -10: + mapserv.sendall(whisper(nick, "User not found, check and try again.")) + return - if int(user_info.get('accesslevel')) < int(user.get("accesslevel")) and accesslevel <= int(user.get("accesslevel")): - user_tree.get_user(name).set('accesslevel', str(accesslevel)) - mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) - user_tree.save() - else: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + if int(user_info.get('accesslevel')) < int(user.get("accesslevel")) and accesslevel <= int(user.get("accesslevel")): + user_tree.get_user(name).set('accesslevel', str(accesslevel)) + mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) + user_tree.save() + else: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == "!adduser": - # A command to give a user access to the bot - !adduser . + # A command to give a user access to the bot - !adduser . if user == -10: - return + return if int(user.get("accesslevel")) != 20: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return - if len(broken_string) < 3: + if len(broken_string) < 3: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return + return if broken_string[1].isdigit() and broken_string[2].isdigit(): al = int(broken_string[1]) stalls = int(broken_string[2]) player_name = " ".join(broken_string[3:]) - user_tree.add_user(player_name, stalls, al) - mapserv.sendall(whisper(nick, "User Added with " + str(stalls) + " slots.")) + user_tree.add_user(player_name, stalls, al) + mapserv.sendall(whisper(nick, "User Added with " + str(stalls) + " slots.")) else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == "!add": - # Allows a player with the correct permissions to add an item for sale - !add - if user == -10: - mapserv.sendall(whisper(nick, "You are unable to add items.")) - return + # Allows a player with the correct permissions to add an item for sale - !add + if user == -10: + mapserv.sendall(whisper(nick, "You are unable to add items.")) + return - if len(broken_string) < 3: + if len(broken_string) < 3: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return - - if int(user.get("accesslevel")) < 5: - mapserv.sendall(whisper(nick, "You are unable to add items.")) - return - - if int(user.get("used_stalls")) >= int(user.get("stalls")): - mapserv.sendall(whisper(nick, "You have no free slots. You may remove an item or wait for something to be sold.")) - return - - if broken_string[1].isdigit() and broken_string[2].isdigit(): - amount = int(broken_string[1]) - price = int(broken_string[2]) - item_name = " ".join(broken_string[3:]) - item_id = ItemDB.findId(item_name) - if item_id == -10: - mapserv.sendall(whisper(nick, "Item not found, check spelling.")) - return - - item = Item() - item.player = nick - item.get = 1 # 1 = get, 0 = give - item.id = item_id - item.amount = amount - item.price = price - trader_state.item = item - - if not trader_state.Trading.testandset(): - mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) - return + return + + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You are unable to add items.")) + return + + if int(user.get("used_stalls")) >= int(user.get("stalls")): + mapserv.sendall(whisper(nick, "You have no free slots. You may remove an item or wait for something to be sold.")) + return + + if broken_string[1].isdigit() and broken_string[2].isdigit(): + amount = int(broken_string[1]) + price = int(broken_string[2]) + item_name = " ".join(broken_string[3:]) + item_id = ItemDB.findId(item_name) + if item_id == -10: + mapserv.sendall(whisper(nick, "Item not found, check spelling.")) + return + + item = Item() + item.player = nick + item.get = 1 # 1 = get, 0 = give + item.id = item_id + item.amount = amount + item.price = price + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return player_id = beingManager.findId(nick) - if player_id != -10: - mapserv.sendall(trade_request(player_id)) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() - else: - mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) - trader_state.reset() - else: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == "!buy": - # Buy a given quantity of an item - !buy - if len(broken_string) != 3: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return - - if broken_string[1].isdigit() and broken_string[2].isdigit(): - amount = int(broken_string[1]) - uid = int(broken_string[2]) - item_info = sale_tree.get_uid(uid) - - if item_info == -10: - mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) - return - - if amount > int(item_info.get("amount")): - mapserv.sendall(whisper(nick, "I do not have that many.")) - return - - item = Item() - item.get = 0 # 1 = get, 0 = give - item.player = nick - item.id = int(item_info.get("itemId")) - item.uid = uid - item.amount = amount - item.price = int(item_info.get("price")) - trader_state.item = item - - if not trader_state.Trading.testandset(): - mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) - return + # Buy a given quantity of an item - !buy + if len(broken_string) != 3: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + + if broken_string[1].isdigit() and broken_string[2].isdigit(): + amount = int(broken_string[1]) + uid = int(broken_string[2]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + if amount > int(item_info.get("amount")): + mapserv.sendall(whisper(nick, "I do not have that many.")) + return + + item = Item() + item.get = 0 # 1 = get, 0 = give + item.player = nick + item.id = int(item_info.get("itemId")) + item.uid = uid + item.amount = amount + item.price = int(item_info.get("price")) + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return player_id = beingManager.findId(nick) - if player_id != -10: - mapserv.sendall(trade_request(player_id)) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() - mapserv.sendall(whisper(nick, "That will be " + str(item.price * item.amount) + "gp.")) - else: - mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) - trader_state.reset() - else: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) + mapserv.sendall(whisper(nick, "That will be " + str(item.price * item.amount) + "gp.")) + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == "!removeuser": - # Remove a user, for whatever reason - !removeuser + # Remove a user, for whatever reason - !removeuser if user == -10: - return + return - if len(broken_string) < 2: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return + if len(broken_string) < 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return if int(user.get("accesslevel")) != 20: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return player_name = " ".join(broken_string[1:]) - check = user_tree.remove_user(player_name) - if check == 1: - mapserv.sendall(whisper(nick, "User Removed.")) - elif check == -10: - mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) + check = user_tree.remove_user(player_name) + if check == 1: + mapserv.sendall(whisper(nick, "User Removed.")) + elif check == -10: + mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) elif broken_string[0] == "!relist": # Relist an item which has expired - !relist . - if user == -10 or len(broken_string) != 2: + if user == -10 or len(broken_string) != 2: mapserv.sendall(whisper(nick, "Syntax incorrect.")) return - if int(user.get("accesslevel")) < 5: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return - if broken_string[1].isdigit(): - uid = int(broken_string[1]) - item_info = sale_tree.get_uid(uid) + if broken_string[1].isdigit(): + uid = int(broken_string[1]) + item_info = sale_tree.get_uid(uid) - if item_info == -10: - mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) - return + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return - if item_info.get('name') != nick: - mapserv.sendall(whisper(nick, "That doesn't belong to you!")) - return + if item_info.get('name') != nick: + mapserv.sendall(whisper(nick, "That doesn't belong to you!")) + return time_relisted = int(item_info.get('relisted')) - if int(item_info.get('relisted')) < 3: - sale_tree.get_uid(uid).set('add_time', str(time.time())) - sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) - sale_tree.save() - mapserv.sendall(whisper(nick, "The item has been successfully relisted.")) - else: + if int(item_info.get('relisted')) < 3: + sale_tree.get_uid(uid).set('add_time', str(time.time())) + sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) + sale_tree.save() + mapserv.sendall(whisper(nick, "The item has been successfully relisted.")) + else: mapserv.sendall(whisper(nick, "This item can no longer be relisted. Please collect it using !getback "+str(uid)+".")) - return + return else: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) + mapserv.sendall(whisper(nick, "Syntax incorrect.")) elif broken_string[0] == "!getback": - # Trade the player back uid, remove from sale_items if trade successful - !getback . - if user == -10 or len(broken_string) != 2: + # Trade the player back uid, remove from sale_items if trade successful - !getback . + if user == -10 or len(broken_string) != 2: mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return - - if int(user.get("accesslevel")) < 5: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return - - if broken_string[1].isdigit(): - uid = int(broken_string[1]) - item_info = sale_tree.get_uid(uid) - - if item_info == -10: - mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) - return - - if item_info.get('name') != nick: - mapserv.sendall(whisper(nick, "That doesn't belong to you!")) - return - - item = Item() - item.get = 0 - item.player = nick - item.id = int(item_info.get("itemId")) - item.uid = uid - item.amount = int(item_info.get("amount")) - item.price = 0 - trader_state.item = item - - if not trader_state.Trading.testandset(): - mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) - return + return + + if int(user.get("accesslevel")) < 5: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if broken_string[1].isdigit(): + uid = int(broken_string[1]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + if item_info.get('name') != nick: + mapserv.sendall(whisper(nick, "That doesn't belong to you!")) + return + + item = Item() + item.get = 0 + item.player = nick + item.id = int(item_info.get("itemId")) + item.uid = uid + item.amount = int(item_info.get("amount")) + item.price = 0 + trader_state.item = item + + if not trader_state.Trading.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) + return player_id = beingManager.findId(nick) - if player_id != -10: - mapserv.sendall(trade_request(player_id)) + if player_id != -10: + mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() - else: - mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) - trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) + trader_state.reset() def main(): logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') @@ -514,19 +514,19 @@ def main(): charport = 0 # Login server packet loop. while True: - #time.sleep(0.1) + #time.sleep(0.1) data = login.recv(1500) if not data: break pb.feed(data) for packet in pb: if packet.is_type(SMSG_LOGIN_DATA): # login succeeded - packet.skip(2) - id1 = packet.read_int32() - accid = packet.read_int32() - id2 = packet.read_int32() - packet.skip(30) - player_node.sex = packet.read_int8() + packet.skip(2) + id1 = packet.read_int32() + accid = packet.read_int32() + id2 = packet.read_int32() + packet.skip(30) + player_node.sex = packet.read_int8() charip = utils.parse_ip(packet.read_int32()) charport = packet.read_int16() login.close() @@ -559,39 +559,39 @@ def main(): pb.feed(data) for packet in pb: if packet.is_type(SMSG_CHAR_LOGIN): - packet.skip(2) - slots = packet.read_int16() - packet.skip(18) - count = (len(packet.data)-22) / 106 - for i in range(count): - player_node.id = packet.read_int32() - player_node.EXP = packet.read_int32() - player_node.MONEY = packet.read_int32() - packet.skip(30) - player_node.HP = packet.read_int16() - player_node.MAX_HP = packet.read_int16() - player_node.MP = packet.read_int16() - player_node.MAX_MP = packet.read_int16() - packet.skip(8) - player_node.LEVEL = packet.read_int16() - packet.skip(14) - player_node.name = packet.read_string(24) - packet.skip(6) + packet.skip(2) + slots = packet.read_int16() + packet.skip(18) + count = (len(packet.data)-22) / 106 + for i in range(count): + player_node.id = packet.read_int32() + player_node.EXP = packet.read_int32() + player_node.MONEY = packet.read_int32() + packet.skip(30) + player_node.HP = packet.read_int16() + player_node.MAX_HP = packet.read_int16() + player_node.MP = packet.read_int16() + player_node.MAX_MP = packet.read_int16() + packet.skip(8) + player_node.LEVEL = packet.read_int16() + packet.skip(14) + player_node.name = packet.read_string(24) + packet.skip(6) slot = packet.read_int8() - packet.skip(1) - print "Character information recieved:" - print "Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s"\ + packet.skip(1) + print "Character information recieved:" + print "Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s"\ % (player_node.name, player_node.id, player_node.EXP, player_node.MONEY, player_node.HP, player_node.MAX_HP, player_node.MP, player_node.MAX_MP, player_node.LEVEL) - if slot == int(character): - break + if slot == int(character): + break - char_select_packet = PacketOut(CMSG_CHAR_SELECT) - char_select_packet.write_int8(int(character)) - char.sendall(str(char_select_packet)) + char_select_packet = PacketOut(CMSG_CHAR_SELECT) + char_select_packet.write_int8(int(character)) + char.sendall(str(char_select_packet)) elif packet.is_type(SMSG_CHAR_MAP_INFO): - player_node.id = packet.read_int32() - player_node.map = packet.read_string(16) + player_node.id = packet.read_int32() + player_node.map = packet.read_string(16) mapip = utils.parse_ip(packet.read_int32()) mapport = packet.read_int16() char.close() @@ -633,379 +633,379 @@ def main(): for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected - logging.info("Map login success.") - packet.skip(4) - coord_data = packet.read_coord_dir() - player_node.x = coord_data[0] - player_node.y = coord_data[1] - player_node.direction = coord_data[2] - print "Starting Postion: %s %s %s" % (player_node.map, player_node.x, player_node.y) + logging.info("Map login success.") + packet.skip(4) + coord_data = packet.read_coord_dir() + player_node.x = coord_data[0] + player_node.y = coord_data[1] + player_node.direction = coord_data[2] + print "Starting Postion: %s %s %s" % (player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) # map loaded - # A Thread to send a shop broadcast: also keeps the network active to prevent timeouts. - shop_broadcaster.start() + # A Thread to send a shop broadcast: also keeps the network active to prevent timeouts. + shop_broadcaster.start() elif packet.is_type(SMSG_WHISPER): - msg_len = packet.read_int16() - 26 + msg_len = packet.read_int16() - 26 nick = packet.read_string(24) message = packet.read_raw_string(msg_len) - logging.info("Whisper: " + nick + ": " + message) - if nick != "guild": - process_whisper(nick, utils.remove_colors(message), mapserv) + logging.info("Whisper: " + nick + ": " + message) + if nick != "guild": + process_whisper(nick, utils.remove_colors(message), mapserv) elif packet.is_type(SMSG_PLAYER_CHAT): # server speech - msg_len = packet.read_int16() - 2 - being_id = packet.read_int32() + msg_len = packet.read_int16() - 2 + being_id = packet.read_int32() message = packet.read_string(msg_len) if "automaticly banned for spam" in message: time.sleep(3) elif packet.is_type(SMSG_BEING_CHAT): # char speech - msg_len = packet.read_int16() - 2 - being_id = packet.read_int32() + msg_len = packet.read_int16() - 2 + being_id = packet.read_int32() message = packet.read_string(msg_len) elif packet.is_type(SMSG_WALK_RESPONSE): - packet.read_int32() - coord_data = packet.read_coord_pair() - player_node.x = coord_data[2] - player_node.y = coord_data[3] + packet.read_int32() + coord_data = packet.read_coord_pair() + player_node.x = coord_data[2] + player_node.y = coord_data[3] elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): - stat_type = packet.read_int16() - value = packet.read_int32() - if stat_type == 0x0005: - player_node.HP = value - elif stat_type == 0x0006: - player_node.MaxHP = value - elif stat_type == 0x0007: - player_node.MP = value - elif stat_type == 0x0008: - player_node.MaxMP = value - elif stat_type == 0x000b: - player_node.LEVEL = value - print "Level changed: %s" % value - elif stat_type == 0x0018: - print "Weight changed from %s/%s to %s/%s" % (player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) - logging.info("Weight changed from %s/%s to %s/%s", player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) - player_node.WEIGHT = value - elif stat_type == 0x0019: - print "Max Weight: %s" % value - player_node.MaxWEIGHT = value + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0005: + player_node.HP = value + elif stat_type == 0x0006: + player_node.MaxHP = value + elif stat_type == 0x0007: + player_node.MP = value + elif stat_type == 0x0008: + player_node.MaxMP = value + elif stat_type == 0x000b: + player_node.LEVEL = value + print "Level changed: %s" % value + elif stat_type == 0x0018: + print "Weight changed from %s/%s to %s/%s" % (player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + logging.info("Weight changed from %s/%s to %s/%s", player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + player_node.WEIGHT = value + elif stat_type == 0x0019: + print "Max Weight: %s" % value + player_node.MaxWEIGHT = value elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): - stat_type = packet.read_int16() - value = packet.read_int32() - if stat_type == 0x0001: - player_node.EXP = value - elif stat_type == 0x0014: - logging.info("Money Changed from %s, to %s", player_node.MONEY, value) - print "Money Changed from %s, to %s" % (player_node.MONEY, value) - player_node.MONEY = value - elif stat_type == 0x0016: - player_node.EXP_NEEDED = value - print "Exp Needed: %s" % player_node.EXP_NEEDED + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0001: + player_node.EXP = value + elif stat_type == 0x0014: + logging.info("Money Changed from %s, to %s", player_node.MONEY, value) + print "Money Changed from %s, to %s" % (player_node.MONEY, value) + player_node.MONEY = value + elif stat_type == 0x0016: + player_node.EXP_NEEDED = value + print "Exp Needed: %s" % player_node.EXP_NEEDED elif packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_BEING_VISIBLE)\ or packet.is_type(SMSG_PLAYER_MOVE) or packet.is_type(SMSG_PLAYER_UPDATE_1)\ or packet.is_type(SMSG_PLAYER_UPDATE_2): - being_id = packet.read_int32() + being_id = packet.read_int32() packet.skip(8) - job = packet.read_int16() - if being_id not in beingManager.container: - if job == 0 and id >= 110000000 and (packet.is_type(SMSG_BEING_MOVE)\ + job = packet.read_int16() + if being_id not in beingManager.container: + if job == 0 and id >= 110000000 and (packet.is_type(SMSG_BEING_MOVE)\ or packet.is_type(SMSG_BEING_VISIBLE)): - continue - # Add the being to the BeingManager, and request name. - beingManager.container[being_id] = Being(being_id, job) - requestName = PacketOut(0x0094) - requestName.write_int32(being_id) - mapserv.sendall(str(requestName)) - - packet.skip(8) - - if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): - packet.read_int32() - - packet.skip(22) - - if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): - coord_data = packet.read_coord_pair() - beingManager.container[being_id].dst_x = coord_data[2] - beingManager.container[being_id].dst_y = coord_data[3] - else: - coord_data = packet.read_coord_dir() - beingManager.container[being_id].x = coord_data[0] + continue + # Add the being to the BeingManager, and request name. + beingManager.container[being_id] = Being(being_id, job) + requestName = PacketOut(0x0094) + requestName.write_int32(being_id) + mapserv.sendall(str(requestName)) + + packet.skip(8) + + if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): + packet.read_int32() + + packet.skip(22) + + if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): + coord_data = packet.read_coord_pair() + beingManager.container[being_id].dst_x = coord_data[2] + beingManager.container[being_id].dst_y = coord_data[3] + else: + coord_data = packet.read_coord_dir() + beingManager.container[being_id].x = coord_data[0] beingManager.container[being_id].y = coord_data[1] - beingManager.container[being_id].direction = coord_data[2] - - elif packet.is_type(SMSG_BEING_NAME_RESPONSE): - being_id = packet.read_int32() - if being_id in beingManager.container: - beingManager.container[being_id].name = packet.read_string(24) - - elif packet.is_type(SMSG_BEING_REMOVE): - being_id = packet.read_int32() - if being_id in beingManager.container: - del beingManager.container[being_id] - - elif packet.is_type(SMSG_PLAYER_WARP): - player_node.map = packet.read_string(16) - player_node.x = packet.read_int16() - player_node.y = packet.read_int16() - logging.info("Player warped.") + beingManager.container[being_id].direction = coord_data[2] + + elif packet.is_type(SMSG_BEING_NAME_RESPONSE): + being_id = packet.read_int32() + if being_id in beingManager.container: + beingManager.container[being_id].name = packet.read_string(24) + + elif packet.is_type(SMSG_BEING_REMOVE): + being_id = packet.read_int32() + if being_id in beingManager.container: + del beingManager.container[being_id] + + elif packet.is_type(SMSG_PLAYER_WARP): + player_node.map = packet.read_string(16) + player_node.x = packet.read_int16() + player_node.y = packet.read_int16() + logging.info("Player warped.") mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) - elif packet.is_type(SMSG_BEING_ACTION): - src_being = packet.read_int32() - dst_being = packet.read_int32() - packet.skip(12) - param1 = packet.read_int16() - packet.skip(2) - action_type = packet.read_int8() + elif packet.is_type(SMSG_BEING_ACTION): + src_being = packet.read_int32() + dst_being = packet.read_int32() + packet.skip(12) + param1 = packet.read_int16() + packet.skip(2) + action_type = packet.read_int8() - if src_being in beingManager.container: - if action_type == 0: # Damage - beingManager.container[src_being].action = "attack" - beingManager.container[src_being].target = dst_being + if src_being in beingManager.container: + if action_type == 0: # Damage + beingManager.container[src_being].action = "attack" + beingManager.container[src_being].target = dst_being - elif action_type == 0x02: # Sit - beingManager.container[src_being].action = "sit" + elif action_type == 0x02: # Sit + beingManager.container[src_being].action = "sit" - elif action_type == 0x03: # Stand up - beingManager.container[src_being].action = "stand" + elif action_type == 0x03: # Stand up + beingManager.container[src_being].action = "stand" elif packet.is_type(SMSG_PLAYER_INVENTORY_ADD): - item = Item() + item = Item() item.index = packet.read_int16() - inventory_offset - item.amount = packet.read_int16() - item.itemId = packet.read_int16() - item.identified = packet.read_int8() - packet.read_int8() - item.refine = packet.read_int8() - packet.skip(8) - item.equipType = packet.read_int16() - item.itemType = packet.read_int8() - err = packet.read_int8() + item.amount = packet.read_int16() + item.itemId = packet.read_int16() + item.identified = packet.read_int8() + packet.read_int8() + item.refine = packet.read_int8() + packet.skip(8) + item.equipType = packet.read_int16() + item.itemType = packet.read_int8() + err = packet.read_int8() if err == 0: - if item.index in player_node.inventory: - player_node.inventory[item.index].amount += item.amount - else: - player_node.inventory[item.index] = item + if item.index in player_node.inventory: + player_node.inventory[item.index].amount += item.amount + else: + player_node.inventory[item.index] = item - print "Picked up: %s, Amount: %s" % (ItemDB.getItem(item.itemId).name, item.amount) - logging.info("Picked up: %s, Amount: %s", ItemDB.getItem(item.itemId).name, str(item.amount)) + print "Picked up: %s, Amount: %s" % (ItemDB.getItem(item.itemId).name, item.amount) + logging.info("Picked up: %s, Amount: %s", ItemDB.getItem(item.itemId).name, str(item.amount)) elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): - index = packet.read_int16() - inventory_offset + index = packet.read_int16() - inventory_offset amount = packet.read_int16() - print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) - logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) - if index in player_node.inventory: - player_node.inventory[index].amount -= amount - if player_node.inventory[index].amount == 0: - del player_node.inventory[index] + print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) + logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + if index in player_node.inventory: + player_node.inventory[index].amount -= amount + if player_node.inventory[index].amount == 0: + del player_node.inventory[index] elif packet.is_type(SMSG_PLAYER_INVENTORY): - player_node.inventory.clear() # Clear the inventory - incase of new index. - packet.skip(2) - number = (len(packet.data)-2) / 18 + player_node.inventory.clear() # Clear the inventory - incase of new index. + packet.skip(2) + number = (len(packet.data)-2) / 18 for loop in range(number): - item = Item() - item.index = packet.read_int16() - inventory_offset - item.itemId = packet.read_int16() - item.itemType = packet.read_int8() - item.identified = packet.read_int8() - item.amount = packet.read_int16() - item.arrow = packet.read_int16() - packet.skip(8) # Cards - player_node.inventory[item.index] = item + item = Item() + item.index = packet.read_int16() - inventory_offset + item.itemId = packet.read_int16() + item.itemType = packet.read_int8() + item.identified = packet.read_int8() + item.amount = packet.read_int16() + item.arrow = packet.read_int16() + packet.skip(8) # Cards + player_node.inventory[item.index] = item elif packet.is_type(SMSG_PLAYER_EQUIPMENT): - packet.read_int16() - number = (len(packet.data)) / 20 + packet.read_int16() + number = (len(packet.data)) / 20 for loop in range(number): - item = Item() - item.index = packet.read_int16() - inventory_offset - item.itemId = packet.read_int16() - item.itemType = packet.read_int8() - item.identified = packet.read_int8() - packet.skip(2) - item.equipType = packet.read_int16() - packet.skip(1) - item.refine = packet.read_int8() - packet.skip(8) - item.amount = 1 - player_node.inventory[item.index] = item - - for item in player_node.inventory: - print "Name: %s, Id: %s, Index: %s, Amount: %s." % \ + item = Item() + item.index = packet.read_int16() - inventory_offset + item.itemId = packet.read_int16() + item.itemType = packet.read_int8() + item.identified = packet.read_int8() + packet.skip(2) + item.equipType = packet.read_int16() + packet.skip(1) + item.refine = packet.read_int8() + packet.skip(8) + item.amount = 1 + player_node.inventory[item.index] = item + + for item in player_node.inventory: + print "Name: %s, Id: %s, Index: %s, Amount: %s." % \ (ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) - elif packet.is_type(SMSG_TRADE_REQUEST): - print "SMSG_TRADE_REQUEST" - name = packet.read_string(24) - logging.info("Trade request: " + name) - - elif packet.is_type(SMSG_TRADE_RESPONSE): - print "SMSG_TRADE_RESPONSE" - response = packet.read_int8() - time.sleep(0.2) - if response == 0: - logging.info("Trade response: Too far away.") - if trader_state.item: - mapserv.sendall(whisper(trader_state.item.player, "You are too far away.")) - elif trader_state.money: - mapserv.sendall(whisper(trader_state.money, "You are too far away.")) - trader_state.reset() - - elif response == 3: - logging.info("Trade response: Trade accepted.") - if trader_state.item: - if trader_state.item.get == 1: # add - mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) - elif trader_state.item.get == 0: # buy - if player_node.find_inventory_index(trader_state.item.id) != -10: - mapserv.sendall(trade_add_item(player_node.find_inventory_index(trader_state.item.id), trader_state.item.amount)) - mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) - if trader_state.item.price == 0: # getback - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - trader_state.complete = 1 - - elif trader_state.money: # money - amount = int(user_tree.get_user(trader_state.money).get('money')) - mapserv.sendall(trade_add_item(0-inventory_offset, amount)) - mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - trader_state.complete = 1 - - elif response == 4: - logging.info("Trade response: Trade cancelled") - trader_state.reset() - - elif packet.is_type(SMSG_TRADE_ITEM_ADD): - print "SMSG_TRADE_ITEM_ADD" - amount = packet.read_int32() - item_id = packet.read_int16() - if trader_state.item and trader_state.money == 0: - if trader_state.item.get == 1: # add - if amount == trader_state.item.amount and item_id == trader_state.item.id: - trader_state.complete = 1 - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - else: - mapserv.sendall(whisper(trader_state.item.player, "Thats not the right item.")) - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - - elif trader_state.item.get == 0: # buy - if amount == trader_state.item.price * trader_state.item.amount and item_id == 0: - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - trader_state.complete = 1 - elif item_id == 0 and amount != trader_state.item.price * trader_state.item.amount: - trader_state.complete = 0 - else: - if item_id == 0: - mapserv.sendall(whisper(trader_state.item.player, "Please verify you have the correct amount of money and try again.")) - else: - mapserv.sendall(whisper(trader_state.item.player, "Don't give me your itenz.")) - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - - elif trader_state.money: # money - mapserv.sendall(whisper(trader_state.money, "Don't give me your itenz.")) - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - - logging.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) - # Note item_id = 0 is money - - elif packet.is_type(SMSG_TRADE_ITEM_ADD_RESPONSE): - print "SMSG_TRADE_ITEM_ADD_RESPONSE" - index = packet.read_int16() - inventory_offset - amount = packet.read_int16() - response = packet.read_int8() - - if response == 0: - logging.info("Trade item add response: Successfully added item.") - if trader_state.item: - if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! + elif packet.is_type(SMSG_TRADE_REQUEST): + print "SMSG_TRADE_REQUEST" + name = packet.read_string(24) + logging.info("Trade request: " + name) + + elif packet.is_type(SMSG_TRADE_RESPONSE): + print "SMSG_TRADE_RESPONSE" + response = packet.read_int8() + time.sleep(0.2) + if response == 0: + logging.info("Trade response: Too far away.") + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You are too far away.")) + elif trader_state.money: + mapserv.sendall(whisper(trader_state.money, "You are too far away.")) + trader_state.reset() + + elif response == 3: + logging.info("Trade response: Trade accepted.") + if trader_state.item: + if trader_state.item.get == 1: # add + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + elif trader_state.item.get == 0: # buy + if player_node.find_inventory_index(trader_state.item.id) != -10: + mapserv.sendall(trade_add_item(player_node.find_inventory_index(trader_state.item.id), trader_state.item.amount)) + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + if trader_state.item.price == 0: # getback + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + + elif trader_state.money: # money + amount = int(user_tree.get_user(trader_state.money).get('money')) + mapserv.sendall(trade_add_item(0-inventory_offset, amount)) + mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + + elif response == 4: + logging.info("Trade response: Trade cancelled") + trader_state.reset() + + elif packet.is_type(SMSG_TRADE_ITEM_ADD): + print "SMSG_TRADE_ITEM_ADD" + amount = packet.read_int32() + item_id = packet.read_int16() + if trader_state.item and trader_state.money == 0: + if trader_state.item.get == 1: # add + if amount == trader_state.item.amount and item_id == trader_state.item.id: + trader_state.complete = 1 + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + else: + mapserv.sendall(whisper(trader_state.item.player, "Thats not the right item.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif trader_state.item.get == 0: # buy + if amount == trader_state.item.price * trader_state.item.amount and item_id == 0: + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 + elif item_id == 0 and amount != trader_state.item.price * trader_state.item.amount: + trader_state.complete = 0 + else: + if item_id == 0: + mapserv.sendall(whisper(trader_state.item.player, "Please verify you have the correct amount of money and try again.")) + else: + mapserv.sendall(whisper(trader_state.item.player, "Don't give me your itenz.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif trader_state.money: # money + mapserv.sendall(whisper(trader_state.money, "Don't give me your itenz.")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + logging.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) + # Note item_id = 0 is money + + elif packet.is_type(SMSG_TRADE_ITEM_ADD_RESPONSE): + print "SMSG_TRADE_ITEM_ADD_RESPONSE" + index = packet.read_int16() - inventory_offset + amount = packet.read_int16() + response = packet.read_int8() + + if response == 0: + logging.info("Trade item add response: Successfully added item.") + if trader_state.item: + if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! if player_node.inventory[index].itemId != trader_state.item.id and \ amount != trader_state.item.amount: mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - # If Trade item add successful - Remove the item from the inventory state. - if index != 0-inventory_offset: # If it's not money - print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) - logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) - if index in player_node.inventory: - player_node.inventory[index].amount -= amount - if player_node.inventory[index].amount == 0: - del player_node.inventory[index] - - elif response == 1: - logging.info("Trade item add response: Failed - player overweight.") - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - if trader_state.item: - mapserv.sendall(whisper(trader_state.item.player, "You are carrying too much weight. Unload and try again.")) - elif response == 2: - if trader_state.item: - mapserv.sendall(whisper(trader_state.item.player, "You have no free slots.")) - logging.info("Trade item add response: Failed - No free slots.") - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - - elif packet.is_type(SMSG_TRADE_OK): - print "SMSG_TRADE_OK" - is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other - if is_ok == 0: - logging.info("Trade OK: Self.") - else: - if trader_state.complete: - mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - else: - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) - - logging.info("Trade Ok: Partner.") - - elif packet.is_type(SMSG_TRADE_CANCEL): - trader_state.reset() - logging.info("Trade Cancel.") - print "SMSG_TRADE_CANCEL" - - elif packet.is_type(SMSG_TRADE_COMPLETE): - # The sale_tree is only ammended after a complete trade packet. - if trader_state.item and trader_state.money == 0: - if trader_state.item.get == 1: # !add - sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) - user_tree.get_user(trader_state.item.player).set('used_stalls', \ + # If Trade item add successful - Remove the item from the inventory state. + if index != 0-inventory_offset: # If it's not money + print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) + logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + if index in player_node.inventory: + player_node.inventory[index].amount -= amount + if player_node.inventory[index].amount == 0: + del player_node.inventory[index] + + elif response == 1: + logging.info("Trade item add response: Failed - player overweight.") + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You are carrying too much weight. Unload and try again.")) + elif response == 2: + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "You have no free slots.")) + logging.info("Trade item add response: Failed - No free slots.") + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + elif packet.is_type(SMSG_TRADE_OK): + print "SMSG_TRADE_OK" + is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other + if is_ok == 0: + logging.info("Trade OK: Self.") + else: + if trader_state.complete: + mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + else: + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) + + logging.info("Trade Ok: Partner.") + + elif packet.is_type(SMSG_TRADE_CANCEL): + trader_state.reset() + logging.info("Trade Cancel.") + print "SMSG_TRADE_CANCEL" + + elif packet.is_type(SMSG_TRADE_COMPLETE): + # The sale_tree is only ammended after a complete trade packet. + if trader_state.item and trader_state.money == 0: + if trader_state.item.get == 1: # !add + sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) + user_tree.get_user(trader_state.item.player).set('used_stalls', \ str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) - elif trader_state.item.get == 0: # !buy \ !getback - seller = sale_tree.get_uid(trader_state.item.uid).get('name') - item = sale_tree.get_uid(trader_state.item.uid) - current_amount = int(item.get("amount")) - sale_tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) - if int(item.get("amount")) == 0: - user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ + elif trader_state.item.get == 0: # !buy \ !getback + seller = sale_tree.get_uid(trader_state.item.uid).get('name') + item = sale_tree.get_uid(trader_state.item.uid) + current_amount = int(item.get("amount")) + sale_tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) + if int(item.get("amount")) == 0: + user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ str(int(user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) - sale_tree.remove_item_uid(trader_state.item.uid) + sale_tree.remove_item_uid(trader_state.item.uid) - current_money = int(user_tree.get_user(seller).get("money")) - user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) + current_money = int(user_tree.get_user(seller).get("money")) + user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) - if trader_state.item.price * trader_state.item.amount != 0: - ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) + if trader_state.item.price * trader_state.item.amount != 0: + ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) - elif trader_state.money and trader_state.item == 0: # !money - user_tree.get_user(trader_state.money).set('money', str(0)) + elif trader_state.money and trader_state.item == 0: # !money + user_tree.get_user(trader_state.money).set('money', str(0)) - sale_tree.save() - user_tree.save() - trader_state.reset() - logging.info("Trade Complete.") - print "SMSG_TRADE_COMPLETE" + sale_tree.save() + user_tree.save() + trader_state.reset() + logging.info("Trade Complete.") + print "SMSG_TRADE_COMPLETE" else: - pass - #print "Unhandled Packet: %s" % hex(packet.get_type()) + pass + #print "Unhandled Packet: %s" % hex(packet.get_type()) # On Disconnect/Exit shop_broadcaster.stop() diff --git a/player.py b/player.py index a63218d..156030a 100644 --- a/player.py +++ b/player.py @@ -4,28 +4,28 @@ class Item: class Player: def __init__(self, name): self.inventory = {} - self.storage = [] - self.name = name - self.id = 0 - self.sex = 0 - self.map = "" - self.x = 0 - self.y = 0 + self.storage = [] + self.name = name + self.id = 0 + self.sex = 0 + self.map = "" + self.x = 0 + self.y = 0 - self.EXP_NEEDED = 0 - self.EXP = 0 - self.MONEY = 0 - self.LEVEL = 0 - self.HP = 0 - self.MaxHP = 0 - self.MP = 0 - self.MaxMP = 0 - self.WEIGHT = 0 - self.MaxWEIGHT = 0 + self.EXP_NEEDED = 0 + self.EXP = 0 + self.MONEY = 0 + self.LEVEL = 0 + self.HP = 0 + self.MaxHP = 0 + self.MP = 0 + self.MaxMP = 0 + self.WEIGHT = 0 + self.MaxWEIGHT = 0 def find_inventory_index(self, item_id): - for item in self.inventory: - if item > 1: - if self.inventory[item].itemId == item_id: - return item - return -10 # Not found - bug somewhere! + for item in self.inventory: + if item > 1: + if self.inventory[item].itemId == item_id: + return item + return -10 # Not found - bug somewhere! diff --git a/tradey.py b/tradey.py index bb83960..9c8703b 100644 --- a/tradey.py +++ b/tradey.py @@ -7,82 +7,82 @@ class UserTree: self.root = self.tree.getroot() def add_user(self, name, stalls, al): - if self.get_user(name) == -10: - user = SubElement(self.root, "user") - user.set("name", name) - user.set("stalls", str(stalls)) + if self.get_user(name) == -10: + user = SubElement(self.root, "user") + user.set("name", name) + user.set("stalls", str(stalls)) user.set("used_stalls", str(0)) - user.set("money", str(0)) - user.set("id", str(0)) - user.set("accesslevel", str(al)) - self.save() + user.set("money", str(0)) + user.set("id", str(0)) + user.set("accesslevel", str(al)) + self.save() def get_user(self, name): - for elem in self.root: - if elem.get("name") == name: - return elem - return -10 + for elem in self.root: + if elem.get("name") == name: + return elem + return -10 def remove_user(self, name): - for elem in self.root: - if elem.get("name") == name: - self.root.remove(elem) - self.save() - return 1 - return -10 + for elem in self.root: + if elem.get("name") == name: + self.root.remove(elem) + self.save() + return 1 + return -10 def save(self): - # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/user.xml") + # Be sure to call save() after any changes to the tree. + self.tree = ElementTree(self.root) + self.tree.write("data/user.xml") class ItemTree: def __init__(self): self.tree = ElementTree(file="data/sale.xml") self.root = self.tree.getroot() - self.u_id = set() + self.u_id = set() - for elem in self.root: - self.u_id.add(int(elem.get("uid"))) + for elem in self.root: + self.u_id.add(int(elem.get("uid"))) def getId(self): - id_itter = 1 - while id_itter in self.u_id: - id_itter += 1 - self.u_id.add(id_itter) - return id_itter + id_itter = 1 + while id_itter in self.u_id: + id_itter += 1 + self.u_id.add(id_itter) + return id_itter def remove_id(self, uid): - # Free up used id's. - self.u_id.remove(uid) + # Free up used id's. + self.u_id.remove(uid) def add_item(self, name, item_id, amount, price): - user = SubElement(self.root, "item") - user.set("name", name) - user.set("itemId", str(item_id)) - user.set("price", str(price)) - user.set("add_time", str(time.time())) - user.set("relisted", str(0)) - user.set("amount", str(amount)) - user.set("uid", str(self.getId())) - self.save() + user = SubElement(self.root, "item") + user.set("name", name) + user.set("itemId", str(item_id)) + user.set("price", str(price)) + user.set("add_time", str(time.time())) + user.set("relisted", str(0)) + user.set("amount", str(amount)) + user.set("uid", str(self.getId())) + self.save() def get_uid(self, uid): - for elem in self.root: - if elem.get("uid") == str(uid): - return elem - return -10 + for elem in self.root: + if elem.get("uid") == str(uid): + return elem + return -10 def remove_item_uid(self, uid): - for elem in self.root: - if elem.get("uid") == str(uid): - self.root.remove(elem) - self.remove_id(uid) - self.save() - return 1 - return -10 + for elem in self.root: + if elem.get("uid") == str(uid): + self.root.remove(elem) + self.remove_id(uid) + self.save() + return 1 + return -10 def save(self): - # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/sale.xml") + # Be sure to call save() after any changes to the tree. + self.tree = ElementTree(self.root) + self.tree.write("data/sale.xml") diff --git a/utils.py b/utils.py index 8e7f839..d770eb4 100644 --- a/utils.py +++ b/utils.py @@ -15,9 +15,9 @@ def parse_ip(a): def remove_colors(msg): if len(msg) > 2: for f in range(len(msg)-2): - while (len(msg) > f + 2) and (msg[f] == "#")\ - and (msg[f+1] == "#"): - msg = msg[0:f]+msg[f+3:] + while (len(msg) > f + 2) and (msg[f] == "#")\ + and (msg[f+1] == "#"): + msg = msg[0:f]+msg[f+3:] return msg # Encode string - used with 4144 shop compatibility. @@ -26,12 +26,12 @@ def encode_str(value, size): base = 94 start = 33 while value: - output += struct.pack(' 500: - item_struct = Item() - item_struct.name = item.get('name') - if item.get('weight'): - item_struct.weight = item.get('weight') - item_struct.description = item.get('description') + item_struct = Item() + item_struct.name = item.get('name') + if item.get('weight'): + item_struct.weight = item.get('weight') + item_struct.description = item.get('description') self.item_names[int(item.get('id'))] = item_struct def getItem(self, item_id): - return self.item_names[item_id] + return self.item_names[item_id] def findId(self, name): - for item_id in self.item_names: - if self.item_names[item_id].name == name: - return item_id - return -10 #Not found + for item_id in self.item_names: + if self.item_names[item_id].name == name: + return item_id + return -10 #Not found class ItemLog: """ Writes all sales to a log file, for later processing.""" @@ -69,47 +69,47 @@ class ItemLog: def add_item(self, item_id, amount, price): file_node = open(self.log_file, 'a') - file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+"\n") - file_node.close() + file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+"\n") + file_node.close() class TraderState: """ Stores information regarding a trade request""" def __init__(self): - self.Trading = mutex.mutex() - self.item = 0 - self.money = 0 - self.complete = 0 + self.Trading = mutex.mutex() + self.item = 0 + self.money = 0 + self.complete = 0 self.timer = 0 def reset(self): - self.Trading.unlock() - self.item = 0 - self.complete = 0 - self.money = 0 + self.Trading.unlock() + self.item = 0 + self.complete = 0 + self.money = 0 self.timer = 0 class Broadcast: """Send a message to the server every 5 minutes to avoid a timeout.""" def __init__(self): - self.mapserv = 0 - self.Active = False - self.Timer = 0 - self.shop_broadcast = threading.Thread(target=self.send_broadcast, args=()) + self.mapserv = 0 + self.Active = False + self.Timer = 0 + self.shop_broadcast = threading.Thread(target=self.send_broadcast, args=()) def send_broadcast(self): - while self.Active: - if (time.time() - self.Timer) > 5 * 60: - self.mapserv.sendall(emote(193)) - self.Timer = time.time() - print "shop_broadcast" - else: - time.sleep(0.1) + while self.Active: + if (time.time() - self.Timer) > 5 * 60: + self.mapserv.sendall(emote(193)) + self.Timer = time.time() + print "shop_broadcast" + else: + time.sleep(0.1) def start(self): - self.Active = True - self.shop_broadcast.start() + self.Active = True + self.shop_broadcast.start() def stop(self): - self.Active = False - self.shop_broadcast.join() + self.Active = False + self.shop_broadcast.join() -- cgit v1.2.3-70-g09d2 From fe235df396611baa4f61b08c7fe7ba65f331f7fe Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:15:58 +0200 Subject: repair indentation --- main.py | 11 +++++++++-- tradey.py | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) mode change 100644 => 100755 main.py diff --git a/main.py b/main.py old mode 100644 new mode 100755 index 41b428d..6a83c53 --- a/main.py +++ b/main.py @@ -18,8 +18,15 @@ import sys import time import string + + from being import * -from data.config import * +try: + from config import * +except: + print "no config file found. please move config.py.template to config.py and edit to your needs!" + exit(0); + from net.packet import * from net.protocol import * from net.packet_out import * @@ -101,7 +108,7 @@ def process_whisper(nick, msg, mapserv): msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" - mapserv.sendall(whisper(nick, msg)) + mapserv.sendall(whisper(nick, msg)) money = int(user.get('money')) mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) diff --git a/tradey.py b/tradey.py index 9c8703b..153d645 100644 --- a/tradey.py +++ b/tradey.py @@ -24,7 +24,7 @@ class UserTree: return -10 def remove_user(self, name): - for elem in self.root: + for elem in self.root: if elem.get("name") == name: self.root.remove(elem) self.save() @@ -74,7 +74,7 @@ class ItemTree: return -10 def remove_item_uid(self, uid): - for elem in self.root: + for elem in self.root: if elem.get("uid") == str(uid): self.root.remove(elem) self.remove_id(uid) -- cgit v1.2.3-70-g09d2 From d845907f7e7e155490d4247c18be25fd0b96edc7 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:19:50 +0200 Subject: Use config file for username and password --- main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 6a83c53..a1d2490 100755 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ import string from being import * try: - from config import * + import config except: print "no config file found. please move config.py.template to config.py and edit to your needs!" exit(0); @@ -500,12 +500,12 @@ def main(): logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') logging.info("Bot Started.") - account = sys.argv[1] - password = sys.argv[2] - character = sys.argv[3] + account = config.account + password = config.password + character = config.character login = socket.socket() - login.connect((server, port)) + login.connect((config.server, config.port)) print("Login connected") login_packet = PacketOut(0x0064) -- cgit v1.2.3-70-g09d2 From 347f41eac9e33743172d319bcc2a4c7283497ccf Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:25:45 +0200 Subject: Adding copyright notes --- being.py | 12 ++++++++++++ main.py | 5 ++++- player.py | 11 +++++++++++ tradey.py | 11 +++++++++++ utils.py | 11 +++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/being.py b/being.py index 52a2e1b..e5d0b95 100644 --- a/being.py +++ b/being.py @@ -1,3 +1,12 @@ +#!/usr/bin/python +""" + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org +""" + def job_type(job): if (job <= 25 or (job >= 4001 and job <= 4049)): return "player" @@ -28,3 +37,6 @@ class Being: self.job = job self.target = 0 self.type = job_type(job) + +if __name__ == '__main__': + print "Do not run this file directly. Run main.py" diff --git a/main.py b/main.py index a1d2490..7ef7b55 100755 --- a/main.py +++ b/main.py @@ -1,7 +1,10 @@ +#!/usr/bin/python """ + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller - This package implements an Automated Market Bot for "The Mana World" a 2D MMORPG. + tradey, a package, which implements an Automated Market Bot for "The Mana World" a 2D MMORPG. - Currently permissions are defined as: -1 (blocked), 0 (normal user), 5 (seller), 20 (admin). - An item will only be listed for a period of one week, and can be relisted diff --git a/player.py b/player.py index 156030a..2e3eafa 100644 --- a/player.py +++ b/player.py @@ -1,3 +1,11 @@ +#!/usr/bin/python +""" + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org +""" class Item: pass @@ -29,3 +37,6 @@ class Player: if self.inventory[item].itemId == item_id: return item return -10 # Not found - bug somewhere! + +if __name__ == '__main__': + print "Do not run this file directly. Run main.py" diff --git a/tradey.py b/tradey.py index 153d645..add8256 100644 --- a/tradey.py +++ b/tradey.py @@ -1,3 +1,11 @@ +#!/usr/bin/python +""" + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org +""" import time from xml.etree.ElementTree import * @@ -86,3 +94,6 @@ class ItemTree: # Be sure to call save() after any changes to the tree. self.tree = ElementTree(self.root) self.tree.write("data/sale.xml") + +if __name__ == '__main__': + print "Do not run this file directly. Run main.py" diff --git a/utils.py b/utils.py index d770eb4..b6bbc3f 100644 --- a/utils.py +++ b/utils.py @@ -1,3 +1,11 @@ +#!/usr/bin/python +""" + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org +""" from xml.etree.ElementTree import ElementTree from player import Item @@ -113,3 +121,6 @@ class Broadcast: def stop(self): self.Active = False self.shop_broadcast.join() + +if __name__ == '__main__': + print "Do not run this file directly. Run main.py" -- cgit v1.2.3-70-g09d2 From e70e71e4e1e354a3120f6c052418cb1432063ffc Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:45:13 +0200 Subject: adding compiled python files (*.pyc) to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 357f8f6..7d7c1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ data/ config.py +*.pyc -- cgit v1.2.3-70-g09d2 From e1907f17bf0bc05c9ca73fbf777462b1f2c1ecc1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 21:48:33 +0200 Subject: even more space changes --- main.py | 2 +- net/packet.py | 106 +++++++++++++++++++++++++++--------------------------- net/packet_out.py | 6 ++-- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/main.py b/main.py index 7ef7b55..68c150e 100755 --- a/main.py +++ b/main.py @@ -996,7 +996,7 @@ def main(): sale_tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) if int(item.get("amount")) == 0: user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ - str(int(user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) + str(int(user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) sale_tree.remove_item_uid(trader_state.item.uid) current_money = int(user_tree.get_user(seller).get("money")) diff --git a/net/packet.py b/net/packet.py index 85a09f9..14ebbc8 100644 --- a/net/packet.py +++ b/net/packet.py @@ -47,99 +47,99 @@ packet_lengths = [ class PacketOut: def __init__(self, out): - self.buff = "" + self.buff = "" self.write_int16(out) def __str__(self): - return self.buff + return self.buff def write_string(self, string_val, length): - self.buff += string_val.ljust(length, '\0') + self.buff += string_val.ljust(length, '\0') def write_int8(self, value): - self.buff += struct.pack("> 8) % 256 - d_1 = (tmp) % 256 - tmp = y - tmp <<= 4 - d_1 |= (tmp >> 8) % 256 - d_2 = tmp % 256 - d_2 |= direction - self.buff += chr(d_0) + chr(d_1) + chr(d_2) + tmp <<= 6 + d_0 = 0 + d_1 = 1 + d_2 = 2 + d_0 = (tmp >> 8) % 256 + d_1 = (tmp) % 256 + tmp = y + tmp <<= 4 + d_1 |= (tmp >> 8) % 256 + d_2 = tmp % 256 + d_2 |= direction + self.buff += chr(d_0) + chr(d_1) + chr(d_2) class PacketIn: def __init__(self, set_data, pkt_type): self.data = set_data - self.pkttype = pkt_type - self.pos = 0 + self.pkttype = pkt_type + self.pos = 0 def is_type(self, pkt_type): - return self.pkttype == pkt_type - + return self.pkttype == pkt_type + def get_type(self): - return self.pkttype + return self.pkttype def read_string(self, length): - msg = self.data[self.pos:self.pos + length] - self.pos = self.pos + length - return msg[:msg.find('\0')] + msg = self.data[self.pos:self.pos + length] + self.pos = self.pos + length + return msg[:msg.find('\0')] def read_raw_string(self, length): - msg = self.data[self.pos:self.pos + length] - self.pos = self.pos + length - return msg + msg = self.data[self.pos:self.pos + length] + self.pos = self.pos + length + return msg def read_int8(self): - int_value = struct.unpack("> 2) - dst_y = self.make_word(struct.unpack("> 2) + dst_y = self.make_word(struct.unpack("> 6) - src_y = (self.make_word(struct.unpack("> 4) - self.pos = self.pos + 5 - return src_x, src_y, dst_x, dst_y + src_x = (self.make_word(struct.unpack("> 6) + src_y = (self.make_word(struct.unpack("> 4) + self.pos = self.pos + 5 + return src_x, src_y, dst_x, dst_y def read_coord_dir(self): - cdata = self.data[self.pos:self.pos + 3] - x = (self.make_word(struct.unpack("> 6) % 255 + cdata = self.data[self.pos:self.pos + 3] + x = (self.make_word(struct.unpack("> 6) % 255 y = (self.make_word(struct.unpack("> 4) % 255 dir = struct.unpack(" Date: Sun, 21 Aug 2011 20:58:24 +0100 Subject: Remove a commentend sleep operation. --- main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main.py b/main.py index 68c150e..8d33d0d 100755 --- a/main.py +++ b/main.py @@ -524,7 +524,6 @@ def main(): charport = 0 # Login server packet loop. while True: - #time.sleep(0.1) data = login.recv(1500) if not data: break -- cgit v1.2.3-70-g09d2 From 2dc21142e1eeb1065c6e06a2877ca59c914aef22 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 22:44:27 +0200 Subject: put data into git repository to make backup easier --- main.py | 4 +++- tradey.py | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 8d33d0d..fdb461f 100755 --- a/main.py +++ b/main.py @@ -986,7 +986,7 @@ def main(): if trader_state.item.get == 1: # !add sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) user_tree.get_user(trader_state.item.player).set('used_stalls', \ - str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) + str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) elif trader_state.item.get == 0: # !buy \ !getback seller = sale_tree.get_uid(trader_state.item.uid).get('name') @@ -1009,6 +1009,8 @@ def main(): sale_tree.save() user_tree.save() + tradey.saveData() + trader_state.reset() logging.info("Trade Complete.") print "SMSG_TRADE_COMPLETE" diff --git a/tradey.py b/tradey.py index add8256..2fe9d5a 100644 --- a/tradey.py +++ b/tradey.py @@ -7,6 +7,8 @@ see www.themanaworld.org """ import time +import os +from subprocess import call from xml.etree.ElementTree import * class UserTree: @@ -95,5 +97,12 @@ class ItemTree: self.tree = ElementTree(self.root) self.tree.write("data/sale.xml") +def saveData(): + cwd = os.getcwd() + os.chdir("data") + call(["git", "commit","-a", '-m transaction']) + os.chdir("..") + + if __name__ == '__main__': print "Do not run this file directly. Run main.py" -- cgit v1.2.3-70-g09d2 From f78ee4cc3781789b74c9baaa931959a821c163fe Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 22:52:25 +0200 Subject: git commit message via parameter --- tradey.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tradey.py b/tradey.py index 2fe9d5a..f439e2d 100644 --- a/tradey.py +++ b/tradey.py @@ -97,10 +97,10 @@ class ItemTree: self.tree = ElementTree(self.root) self.tree.write("data/sale.xml") -def saveData(): +def saveData(commitmessage = "commit"): cwd = os.getcwd() os.chdir("data") - call(["git", "commit","-a", '-m transaction']) + call(["git", "commit","-a", '-m "' + commitmessage + '"']) os.chdir("..") -- cgit v1.2.3-70-g09d2 From 81295ff05acb2617f444468a189fd7ce12998bee Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 21 Aug 2011 21:59:33 +0100 Subject: Add git commit to remove admin operations. --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index fdb461f..8d4e494 100755 --- a/main.py +++ b/main.py @@ -252,6 +252,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('stalls', str(slot)) mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) + tradey.saveData("User: "+player_name+", Slots changed: "+str(slot)) user_tree.save() else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -283,6 +284,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('accesslevel', str(accesslevel)) mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) user_tree.save() + tradey.saveData("User: "+player_name+", Set Access Level: "+str(accesslevel)) else: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return @@ -309,6 +311,7 @@ def process_whisper(nick, msg, mapserv): player_name = " ".join(broken_string[3:]) user_tree.add_user(player_name, stalls, al) mapserv.sendall(whisper(nick, "User Added with " + str(stalls) + " slots.")) + tradey.saveData("User Added: "+player_name+", Slots: "+str(stalls)+", Access Level: "+str(al)) else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -419,6 +422,7 @@ def process_whisper(nick, msg, mapserv): check = user_tree.remove_user(player_name) if check == 1: mapserv.sendall(whisper(nick, "User Removed.")) + tradey.saveData("User Removed: "+player_name) elif check == -10: mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) -- cgit v1.2.3-70-g09d2 From 636741e9f8c577090e7cc3ca8f7c480f3fbee98e Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 22:59:42 +0200 Subject: comment --- tradey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tradey.py b/tradey.py index f439e2d..8ec6c6b 100644 --- a/tradey.py +++ b/tradey.py @@ -98,7 +98,7 @@ class ItemTree: self.tree.write("data/sale.xml") def saveData(commitmessage = "commit"): - cwd = os.getcwd() + # This assumes the current working directory is the tradey directory. os.chdir("data") call(["git", "commit","-a", '-m "' + commitmessage + '"']) os.chdir("..") -- cgit v1.2.3-70-g09d2 From e603178a2e61c3252bfb34dbd66d5b42458cd3af Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 23:02:35 +0200 Subject: tabs->spaces, commit messages for trades --- main.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 8d4e494..0fd9ca2 100755 --- a/main.py +++ b/main.py @@ -252,7 +252,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('stalls', str(slot)) mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) - tradey.saveData("User: "+player_name+", Slots changed: "+str(slot)) + tradey.saveData("User: "+player_name+", Slots changed: "+str(slot)) user_tree.save() else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -284,7 +284,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('accesslevel', str(accesslevel)) mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) user_tree.save() - tradey.saveData("User: "+player_name+", Set Access Level: "+str(accesslevel)) + tradey.saveData("User: "+player_name+", Set Access Level: "+str(accesslevel)) else: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return @@ -311,7 +311,7 @@ def process_whisper(nick, msg, mapserv): player_name = " ".join(broken_string[3:]) user_tree.add_user(player_name, stalls, al) mapserv.sendall(whisper(nick, "User Added with " + str(stalls) + " slots.")) - tradey.saveData("User Added: "+player_name+", Slots: "+str(stalls)+", Access Level: "+str(al)) + tradey.saveData("User Added: "+player_name+", Slots: "+str(stalls)+", Access Level: "+str(al)) else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -422,7 +422,7 @@ def process_whisper(nick, msg, mapserv): check = user_tree.remove_user(player_name) if check == 1: mapserv.sendall(whisper(nick, "User Removed.")) - tradey.saveData("User Removed: "+player_name) + tradey.saveData("User Removed: "+player_name) elif check == -10: mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) @@ -985,12 +985,14 @@ def main(): print "SMSG_TRADE_CANCEL" elif packet.is_type(SMSG_TRADE_COMPLETE): + commitMessage="" # The sale_tree is only ammended after a complete trade packet. if trader_state.item and trader_state.money == 0: if trader_state.item.get == 1: # !add sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) user_tree.get_user(trader_state.item.player).set('used_stalls', \ str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) + commitMessage = "Add" elif trader_state.item.get == 0: # !buy \ !getback seller = sale_tree.get_uid(trader_state.item.uid).get('name') @@ -1007,13 +1009,15 @@ def main(): if trader_state.item.price * trader_state.item.amount != 0: ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) + commitMessage = "Buy or Getback" elif trader_state.money and trader_state.item == 0: # !money user_tree.get_user(trader_state.money).set('money', str(0)) + commitMessage = "Money" sale_tree.save() user_tree.save() - tradey.saveData() + tradey.saveData(commitMessage) trader_state.reset() logging.info("Trade Complete.") -- cgit v1.2.3-70-g09d2 From cd0626bee20295d483e150d5f36def2b296b70ef Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 23:13:05 +0200 Subject: pretty xml --- tradey.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tradey.py b/tradey.py index 8ec6c6b..f2f5ac3 100644 --- a/tradey.py +++ b/tradey.py @@ -44,7 +44,9 @@ class UserTree: def save(self): # Be sure to call save() after any changes to the tree. self.tree = ElementTree(self.root) - self.tree.write("data/user.xml") + f=open("data/user.xml","w") + f.write(etree.tostring(root, pretty_print=True)) + f.close() class ItemTree: def __init__(self): @@ -95,7 +97,9 @@ class ItemTree: def save(self): # Be sure to call save() after any changes to the tree. self.tree = ElementTree(self.root) - self.tree.write("data/sale.xml") + f = open("data/sale.xml", "w") + f.write(etree.tostring(root, pretty_print=True)) + f.close() def saveData(commitmessage = "commit"): # This assumes the current working directory is the tradey directory. -- cgit v1.2.3-70-g09d2 From 09d2d40a841c8436ed782ccda4fd3319f6cb1f05 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 21 Aug 2011 23:35:56 +0200 Subject: Revert "pretty xml" This reverts commit cd0626bee20295d483e150d5f36def2b296b70ef. --- tradey.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tradey.py b/tradey.py index f2f5ac3..8ec6c6b 100644 --- a/tradey.py +++ b/tradey.py @@ -44,9 +44,7 @@ class UserTree: def save(self): # Be sure to call save() after any changes to the tree. self.tree = ElementTree(self.root) - f=open("data/user.xml","w") - f.write(etree.tostring(root, pretty_print=True)) - f.close() + self.tree.write("data/user.xml") class ItemTree: def __init__(self): @@ -97,9 +95,7 @@ class ItemTree: def save(self): # Be sure to call save() after any changes to the tree. self.tree = ElementTree(self.root) - f = open("data/sale.xml", "w") - f.write(etree.tostring(root, pretty_print=True)) - f.close() + self.tree.write("data/sale.xml") def saveData(commitmessage = "commit"): # This assumes the current working directory is the tradey directory. -- cgit v1.2.3-70-g09d2 From a4f48afc93c78ff3eacdb99efa529527d15634e2 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 01:26:51 +0100 Subject: Add more logging information. --- main.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 0fd9ca2..11ac513 100755 --- a/main.py +++ b/main.py @@ -513,7 +513,7 @@ def main(): login = socket.socket() login.connect((config.server, config.port)) - print("Login connected") + logging.info("Login connected") login_packet = PacketOut(0x0064) login_packet.write_int32(0) @@ -551,7 +551,7 @@ def main(): char = socket.socket() char.connect((charip, charport)) - print("Char connected") + logging.info("Char connected") char_serv_packet = PacketOut(CMSG_CHAR_SERVER_CONNECT) char_serv_packet.write_int32(accid) char_serv_packet.write_int32(id1) @@ -592,14 +592,15 @@ def main(): packet.skip(6) slot = packet.read_int8() packet.skip(1) - print "Character information recieved:" - print "Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s"\ - % (player_node.name, player_node.id, player_node.EXP, player_node.MONEY, player_node.HP, player_node.MAX_HP, player_node.MP, player_node.MAX_MP, player_node.LEVEL) - if slot == int(character): + logging.info("Character information recieved:") + logging.info("Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s", \ + player_node.name, player_node.id, player_node.EXP, player_node.MONEY, player_node.HP, \ + player_node.MAX_HP, player_node.MP, player_node.MAX_MP, player_node.LEVEL) + if slot == character: break char_select_packet = PacketOut(CMSG_CHAR_SELECT) - char_select_packet.write_int8(int(character)) + char_select_packet.write_int8(character) char.sendall(str(char_select_packet)) elif packet.is_type(SMSG_CHAR_MAP_INFO): @@ -617,7 +618,7 @@ def main(): beingManager.container[player_node.id] = Being(player_node.id, 42) mapserv = socket.socket() mapserv.connect((mapip, mapport)) - print("Map connected") + logging.info("Map connected") mapserv_login_packet = PacketOut(CMSG_MAP_SERVER_CONNECT) mapserv_login_packet.write_int32(accid) mapserv_login_packet.write_int32(player_node.id) @@ -652,7 +653,7 @@ def main(): player_node.x = coord_data[0] player_node.y = coord_data[1] player_node.direction = coord_data[2] - print "Starting Postion: %s %s %s" % (player_node.map, player_node.x, player_node.y) + logging.info("Starting Postion: %s %s %s", player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) # map loaded # A Thread to send a shop broadcast: also keeps the network active to prevent timeouts. shop_broadcaster.start() @@ -669,8 +670,6 @@ def main(): msg_len = packet.read_int16() - 2 being_id = packet.read_int32() message = packet.read_string(msg_len) - if "automaticly banned for spam" in message: - time.sleep(3) elif packet.is_type(SMSG_BEING_CHAT): # char speech msg_len = packet.read_int16() - 2 @@ -765,7 +764,7 @@ def main(): player_node.map = packet.read_string(16) player_node.x = packet.read_int16() player_node.y = packet.read_int16() - logging.info("Player warped.") + logging.info("Player warped: %s %s %s", player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) elif packet.is_type(SMSG_BEING_ACTION): @@ -852,10 +851,11 @@ def main(): item.amount = 1 player_node.inventory[item.index] = item + logging.info("Inventory information received:") for item in player_node.inventory: - print "Name: %s, Id: %s, Index: %s, Amount: %s." % \ - (ItemDB.getItem(player_node.inventory[item].itemId).name, \ - player_node.inventory[item].itemId, item, player_node.inventory[item].amount) + logging.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ + ItemDB.getItem(player_node.inventory[item].itemId).name, \ + player_node.inventory[item].itemId, item, player_node.inventory[item].amount) elif packet.is_type(SMSG_TRADE_REQUEST): print "SMSG_TRADE_REQUEST" @@ -941,7 +941,7 @@ def main(): logging.info("Trade item add response: Successfully added item.") if trader_state.item: if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! - if player_node.inventory[index].itemId != trader_state.item.id and \ + if player_node.inventory[index].itemId != trader_state.item.id or \ amount != trader_state.item.amount: mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) -- cgit v1.2.3-70-g09d2 From 60addbccce88882ec783029c10299affe2bfe536 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 01:54:55 +0100 Subject: Hide items that need relisting from the !selllist. --- main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 11ac513..a567976 100755 --- a/main.py +++ b/main.py @@ -74,9 +74,10 @@ def process_whisper(nick, msg, mapserv): data = '\302\202B1' for elem in sale_tree.root: - data += utils.encode_str(int(elem.get("itemId")), 2) - data += utils.encode_str(int(elem.get("price")), 4) - data += utils.encode_str(int(elem.get("amount")), 3) + if time.time() - float(elem.get('add_time')) < 604800: + data += utils.encode_str(int(elem.get("itemId")), 2) + data += utils.encode_str(int(elem.get("price")), 4) + data += utils.encode_str(int(elem.get("amount")), 3) mapserv.sendall(whisper(nick, data)) elif broken_string[0] == '!buyitem': -- cgit v1.2.3-70-g09d2 From 154d4127d18393aa3ec66a4c00e2c6a72d503307 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 09:30:12 +0100 Subject: Replace a few print commands with logging. --- main.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/main.py b/main.py index a567976..98780d3 100755 --- a/main.py +++ b/main.py @@ -696,13 +696,12 @@ def main(): player_node.MaxMP = value elif stat_type == 0x000b: player_node.LEVEL = value - print "Level changed: %s" % value elif stat_type == 0x0018: - print "Weight changed from %s/%s to %s/%s" % (player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) - logging.info("Weight changed from %s/%s to %s/%s", player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + logging.info("Weight changed from %s/%s to %s/%s", \ + player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) player_node.WEIGHT = value elif stat_type == 0x0019: - print "Max Weight: %s" % value + logging.info("Max Weight: %s", value) player_node.MaxWEIGHT = value elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): @@ -712,11 +711,7 @@ def main(): player_node.EXP = value elif stat_type == 0x0014: logging.info("Money Changed from %s, to %s", player_node.MONEY, value) - print "Money Changed from %s, to %s" % (player_node.MONEY, value) player_node.MONEY = value - elif stat_type == 0x0016: - player_node.EXP_NEEDED = value - print "Exp Needed: %s" % player_node.EXP_NEEDED elif packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_BEING_VISIBLE)\ or packet.is_type(SMSG_PLAYER_MOVE) or packet.is_type(SMSG_PLAYER_UPDATE_1)\ @@ -806,14 +801,12 @@ def main(): else: player_node.inventory[item.index] = item - print "Picked up: %s, Amount: %s" % (ItemDB.getItem(item.itemId).name, item.amount) logging.info("Picked up: %s, Amount: %s", ItemDB.getItem(item.itemId).name, str(item.amount)) elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): index = packet.read_int16() - inventory_offset amount = packet.read_int16() - print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) if index in player_node.inventory: player_node.inventory[index].amount -= amount @@ -859,7 +852,6 @@ def main(): player_node.inventory[item].itemId, item, player_node.inventory[item].amount) elif packet.is_type(SMSG_TRADE_REQUEST): - print "SMSG_TRADE_REQUEST" name = packet.read_string(24) logging.info("Trade request: " + name) @@ -900,7 +892,6 @@ def main(): trader_state.reset() elif packet.is_type(SMSG_TRADE_ITEM_ADD): - print "SMSG_TRADE_ITEM_ADD" amount = packet.read_int32() item_id = packet.read_int16() if trader_state.item and trader_state.money == 0: @@ -933,7 +924,6 @@ def main(): # Note item_id = 0 is money elif packet.is_type(SMSG_TRADE_ITEM_ADD_RESPONSE): - print "SMSG_TRADE_ITEM_ADD_RESPONSE" index = packet.read_int16() - inventory_offset amount = packet.read_int16() response = packet.read_int8() @@ -948,7 +938,6 @@ def main(): # If Trade item add successful - Remove the item from the inventory state. if index != 0-inventory_offset: # If it's not money - print "Remove item: %s, Amount: %s" % (ItemDB.getItem(player_node.inventory[index].itemId).name, amount) logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) if index in player_node.inventory: player_node.inventory[index].amount -= amount @@ -967,7 +956,6 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) elif packet.is_type(SMSG_TRADE_OK): - print "SMSG_TRADE_OK" is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other if is_ok == 0: logging.info("Trade OK: Self.") @@ -983,7 +971,6 @@ def main(): elif packet.is_type(SMSG_TRADE_CANCEL): trader_state.reset() logging.info("Trade Cancel.") - print "SMSG_TRADE_CANCEL" elif packet.is_type(SMSG_TRADE_COMPLETE): commitMessage="" @@ -1022,7 +1009,6 @@ def main(): trader_state.reset() logging.info("Trade Complete.") - print "SMSG_TRADE_COMPLETE" else: pass #print "Unhandled Packet: %s" % hex(packet.get_type()) -- cgit v1.2.3-70-g09d2 From 152baa6eb8af6a24c6ee3966f5b47a664e239e84 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 09:33:11 +0100 Subject: Remove SMSG_BEING_ACTION packet handling code. This is not needed for the functioning of the "TradeBot" --- main.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/main.py b/main.py index 98780d3..56de5cd 100755 --- a/main.py +++ b/main.py @@ -763,25 +763,6 @@ def main(): logging.info("Player warped: %s %s %s", player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) - elif packet.is_type(SMSG_BEING_ACTION): - src_being = packet.read_int32() - dst_being = packet.read_int32() - packet.skip(12) - param1 = packet.read_int16() - packet.skip(2) - action_type = packet.read_int8() - - if src_being in beingManager.container: - if action_type == 0: # Damage - beingManager.container[src_being].action = "attack" - beingManager.container[src_being].target = dst_being - - elif action_type == 0x02: # Sit - beingManager.container[src_being].action = "sit" - - elif action_type == 0x03: # Stand up - beingManager.container[src_being].action = "stand" - elif packet.is_type(SMSG_PLAYER_INVENTORY_ADD): item = Item() item.index = packet.read_int16() - inventory_offset @@ -856,7 +837,6 @@ def main(): logging.info("Trade request: " + name) elif packet.is_type(SMSG_TRADE_RESPONSE): - print "SMSG_TRADE_RESPONSE" response = packet.read_int8() time.sleep(0.2) if response == 0: -- cgit v1.2.3-70-g09d2 From acf5d486463147e68b9fab4899f83ce3aaaff107 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 09:44:24 +0100 Subject: Add a relist_time setting to the configuration file. --- config.py.template | 1 + main.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/config.py.template b/config.py.template index 068d432..df11a32 100644 --- a/config.py.template +++ b/config.py.template @@ -3,4 +3,5 @@ server = "caliban.homeip.net" port = 6901 account = "" password = "" +relist_time = 604800 # Time in seconds before an item needs to be relisted. character = 0 #slot character is in, 0 for first, 1 for second, 2 for third diff --git a/main.py b/main.py index 56de5cd..41f5059 100755 --- a/main.py +++ b/main.py @@ -64,7 +64,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "No items for sale.")) for elem in sale_tree.root: - if time.time() - float(elem.get('add_time')) < 604800: # Check if an items time is up. + if time.time() - float(elem.get('add_time')) < config.relist_time: # Check if an items time is up. msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ elem.get("itemId") + "|" + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" mapserv.sendall(whisper(nick, msg)) @@ -74,7 +74,7 @@ def process_whisper(nick, msg, mapserv): data = '\302\202B1' for elem in sale_tree.root: - if time.time() - float(elem.get('add_time')) < 604800: + if time.time() - float(elem.get('add_time')) < config.relist_time: data += utils.encode_str(int(elem.get("itemId")), 2) data += utils.encode_str(int(elem.get("price")), 4) data += utils.encode_str(int(elem.get("amount")), 3) @@ -105,7 +105,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Your have the following items for sale:")) for elem in sale_tree.root: if elem.get('name') == nick: - if time.time() - float(elem.get('add_time')) > 604800: + if time.time() - float(elem.get('add_time')) > config.relist_time: msg = "[expired] [" else: msg = "[selling] [" @@ -184,7 +184,7 @@ def process_whisper(nick, msg, mapserv): if item.isdigit(): # an id for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < 604800) \ + if ((time.time() - float(elem.get('add_time'))) < config.relist_time) \ and int(elem.get("itemId")) == int(item): # Check if an items time is up. msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" @@ -192,7 +192,7 @@ def process_whisper(nick, msg, mapserv): items_found = True else: # an item name for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < 604800) \ + if ((time.time() - float(elem.get('add_time'))) < config.relist_time) \ and item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): # Check if an items time is up. msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" -- cgit v1.2.3-70-g09d2 From 4868a3ce5efcfb5b14c2863d6890e489a6fb4b2c Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 09:45:57 +0100 Subject: Fix a tiny bug in the broadcast thread. --- utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils.py b/utils.py index b6bbc3f..f94feba 100644 --- a/utils.py +++ b/utils.py @@ -119,8 +119,9 @@ class Broadcast: self.shop_broadcast.start() def stop(self): - self.Active = False - self.shop_broadcast.join() + if self.Active = True + self.Active = False + self.shop_broadcast.join() if __name__ == '__main__': print "Do not run this file directly. Run main.py" -- cgit v1.2.3-70-g09d2 From 8e4acb8e54bfbd355766db3f3660c068d4e3e591 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 09:52:10 +0100 Subject: Improve the !info message, when no items are being sold. --- main.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 41f5059..a6c5a03 100755 --- a/main.py +++ b/main.py @@ -102,7 +102,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Your current access level is 0.")) elif int(user.get('accesslevel')) > 0: mapserv.sendall(whisper(nick, "Your current access level is " + user.get('accesslevel') + ".")) - mapserv.sendall(whisper(nick, "Your have the following items for sale:")) + items_for_sale = False for elem in sale_tree.root: if elem.get('name') == nick: if time.time() - float(elem.get('add_time')) > config.relist_time: @@ -112,8 +112,16 @@ def process_whisper(nick, msg, mapserv): msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + + if items_for_sale == False: + mapserv.sendall(whisper(nick, "Your have the following items for sale:")) + items_for_sale = True + mapserv.sendall(whisper(nick, msg)) + if items_for_sale == False: + mapserv.sendall(whisper(nick, "Your have no items for sale.")) + money = int(user.get('money')) mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) stall_msg = "You have " + str(int(user.get('stalls')) - int(user.get('used_stalls'))) + " free slots." -- cgit v1.2.3-70-g09d2 From 6d90f26c9f7b7cd68798eb5fb65f9514472d8ef1 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:24:16 +0100 Subject: Oops dumb mistake. --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index f94feba..2e1d0e8 100644 --- a/utils.py +++ b/utils.py @@ -119,7 +119,7 @@ class Broadcast: self.shop_broadcast.start() def stop(self): - if self.Active = True + if self.Active: self.Active = False self.shop_broadcast.join() -- cgit v1.2.3-70-g09d2 From b9e80443ea8ef7deded058892cff77c0e77d311f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 22 Aug 2011 11:25:20 +0200 Subject: Adding gnufrk as original author of packet buffer class --- net/packet.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/packet.py b/net/packet.py index 14ebbc8..16b4f79 100644 --- a/net/packet.py +++ b/net/packet.py @@ -1,3 +1,6 @@ + +"""The PacketBuffer class has been adapted from source originally released by gnufrk""" + import struct packet_lengths = [ -- cgit v1.2.3-70-g09d2 From b75d6a31f83173f7649317c4651473e1c9731362 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:39:53 +0100 Subject: Move some of the packet handling code. --- main.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/main.py b/main.py index a6c5a03..da5b2b8 100755 --- a/main.py +++ b/main.py @@ -34,6 +34,7 @@ from net.packet import * from net.protocol import * from net.packet_out import * from player import * +import net.packet_handler import tradey import utils @@ -692,25 +693,7 @@ def main(): player_node.y = coord_data[3] elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): - stat_type = packet.read_int16() - value = packet.read_int32() - if stat_type == 0x0005: - player_node.HP = value - elif stat_type == 0x0006: - player_node.MaxHP = value - elif stat_type == 0x0007: - player_node.MP = value - elif stat_type == 0x0008: - player_node.MaxMP = value - elif stat_type == 0x000b: - player_node.LEVEL = value - elif stat_type == 0x0018: - logging.info("Weight changed from %s/%s to %s/%s", \ - player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) - player_node.WEIGHT = value - elif stat_type == 0x0019: - logging.info("Max Weight: %s", value) - player_node.MaxWEIGHT = value + packet_handler.handle_stat_update_1(packet, player_node, logging) elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): stat_type = packet.read_int16() -- cgit v1.2.3-70-g09d2 From 10a88e29dd96066663fe104fe7bcbd7739bbc729 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:43:48 +0100 Subject: oops --- net/packet_handler.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 net/packet_handler.py diff --git a/net/packet_handler.py b/net/packet_handler.py new file mode 100644 index 0000000..48a0a6d --- /dev/null +++ b/net/packet_handler.py @@ -0,0 +1,24 @@ +from packet import * +from protocol import * + +def handle_stat_update_1(packet, player_node, logging): + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0005: + player_node.HP = value + elif stat_type == 0x0006: + player_node.MaxHP = value + elif stat_type == 0x0007: + player_node.MP = value + elif stat_type == 0x0008: + player_node.MaxMP = value + elif stat_type == 0x000b: + player_node.LEVEL = value + elif stat_type == 0x0018: + logging.info("Weight changed from %s/%s to %s/%s", \ + player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + player_node.WEIGHT = value + elif stat_type == 0x0019: + logging.info("Max Weight: %s", value) + player_node.MaxWEIGHT = value + -- cgit v1.2.3-70-g09d2 From 3f0c9291baebc09c764a022e69f250689465e44f Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:49:33 +0100 Subject: Revert "Move some of the packet handling code." This reverts commit b75d6a31f83173f7649317c4651473e1c9731362. --- main.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index da5b2b8..a6c5a03 100755 --- a/main.py +++ b/main.py @@ -34,7 +34,6 @@ from net.packet import * from net.protocol import * from net.packet_out import * from player import * -import net.packet_handler import tradey import utils @@ -693,7 +692,25 @@ def main(): player_node.y = coord_data[3] elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): - packet_handler.handle_stat_update_1(packet, player_node, logging) + stat_type = packet.read_int16() + value = packet.read_int32() + if stat_type == 0x0005: + player_node.HP = value + elif stat_type == 0x0006: + player_node.MaxHP = value + elif stat_type == 0x0007: + player_node.MP = value + elif stat_type == 0x0008: + player_node.MaxMP = value + elif stat_type == 0x000b: + player_node.LEVEL = value + elif stat_type == 0x0018: + logging.info("Weight changed from %s/%s to %s/%s", \ + player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) + player_node.WEIGHT = value + elif stat_type == 0x0019: + logging.info("Max Weight: %s", value) + player_node.MaxWEIGHT = value elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): stat_type = packet.read_int16() -- cgit v1.2.3-70-g09d2 From 5aa34d1f2b0034f0f07009a83c611fa7de41a63e Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:52:28 +0100 Subject: Revert "oops" This reverts commit 10a88e29dd96066663fe104fe7bcbd7739bbc729. --- net/packet_handler.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 net/packet_handler.py diff --git a/net/packet_handler.py b/net/packet_handler.py deleted file mode 100644 index 48a0a6d..0000000 --- a/net/packet_handler.py +++ /dev/null @@ -1,24 +0,0 @@ -from packet import * -from protocol import * - -def handle_stat_update_1(packet, player_node, logging): - stat_type = packet.read_int16() - value = packet.read_int32() - if stat_type == 0x0005: - player_node.HP = value - elif stat_type == 0x0006: - player_node.MaxHP = value - elif stat_type == 0x0007: - player_node.MP = value - elif stat_type == 0x0008: - player_node.MaxMP = value - elif stat_type == 0x000b: - player_node.LEVEL = value - elif stat_type == 0x0018: - logging.info("Weight changed from %s/%s to %s/%s", \ - player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) - player_node.WEIGHT = value - elif stat_type == 0x0019: - logging.info("Max Weight: %s", value) - player_node.MaxWEIGHT = value - -- cgit v1.2.3-70-g09d2 From e713cfd91f9781bd22c1fafbc613bcc1b89e94db Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 10:58:00 +0100 Subject: Remove some more unnecessary packet handling. --- main.py | 50 ++------------------------------------------------ 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/main.py b/main.py index a6c5a03..9150ea1 100755 --- a/main.py +++ b/main.py @@ -675,36 +675,10 @@ def main(): if nick != "guild": process_whisper(nick, utils.remove_colors(message), mapserv) - elif packet.is_type(SMSG_PLAYER_CHAT): # server speech - msg_len = packet.read_int16() - 2 - being_id = packet.read_int32() - message = packet.read_string(msg_len) - - elif packet.is_type(SMSG_BEING_CHAT): # char speech - msg_len = packet.read_int16() - 2 - being_id = packet.read_int32() - message = packet.read_string(msg_len) - - elif packet.is_type(SMSG_WALK_RESPONSE): - packet.read_int32() - coord_data = packet.read_coord_pair() - player_node.x = coord_data[2] - player_node.y = coord_data[3] - elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): stat_type = packet.read_int16() value = packet.read_int32() - if stat_type == 0x0005: - player_node.HP = value - elif stat_type == 0x0006: - player_node.MaxHP = value - elif stat_type == 0x0007: - player_node.MP = value - elif stat_type == 0x0008: - player_node.MaxMP = value - elif stat_type == 0x000b: - player_node.LEVEL = value - elif stat_type == 0x0018: + if stat_type == 0x0018: logging.info("Weight changed from %s/%s to %s/%s", \ player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) player_node.WEIGHT = value @@ -715,9 +689,7 @@ def main(): elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): stat_type = packet.read_int16() value = packet.read_int32() - if stat_type == 0x0001: - player_node.EXP = value - elif stat_type == 0x0014: + if stat_type == 0x0014: logging.info("Money Changed from %s, to %s", player_node.MONEY, value) player_node.MONEY = value @@ -737,23 +709,6 @@ def main(): requestName.write_int32(being_id) mapserv.sendall(str(requestName)) - packet.skip(8) - - if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): - packet.read_int32() - - packet.skip(22) - - if (packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_PLAYER_MOVE)): - coord_data = packet.read_coord_pair() - beingManager.container[being_id].dst_x = coord_data[2] - beingManager.container[being_id].dst_y = coord_data[3] - else: - coord_data = packet.read_coord_dir() - beingManager.container[being_id].x = coord_data[0] - beingManager.container[being_id].y = coord_data[1] - beingManager.container[being_id].direction = coord_data[2] - elif packet.is_type(SMSG_BEING_NAME_RESPONSE): being_id = packet.read_int32() if being_id in beingManager.container: @@ -999,7 +954,6 @@ def main(): logging.info("Trade Complete.") else: pass - #print "Unhandled Packet: %s" % hex(packet.get_type()) # On Disconnect/Exit shop_broadcaster.stop() -- cgit v1.2.3-70-g09d2 From 191114cfa6774d7024cf392794ffa7fd97ee8ebd Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:12:25 +0100 Subject: Clean up more of the packet code. --- main.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 9150ea1..6aff6ef 100755 --- a/main.py +++ b/main.py @@ -589,14 +589,7 @@ def main(): player_node.id = packet.read_int32() player_node.EXP = packet.read_int32() player_node.MONEY = packet.read_int32() - packet.skip(30) - player_node.HP = packet.read_int16() - player_node.MAX_HP = packet.read_int16() - player_node.MP = packet.read_int16() - player_node.MAX_MP = packet.read_int16() - packet.skip(8) - player_node.LEVEL = packet.read_int16() - packet.skip(14) + packet.skip(62) player_node.name = packet.read_string(24) packet.skip(6) slot = packet.read_int8() @@ -830,7 +823,7 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) trader_state.complete = 1 - elif response == 4: + else: logging.info("Trade response: Trade cancelled") trader_state.reset() -- cgit v1.2.3-70-g09d2 From e2eb4a2717bb2661fc25179b0d054b33964bb979 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 22 Aug 2011 12:16:30 +0200 Subject: adding more help messages --- main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/main.py b/main.py index 6aff6ef..7e2e4e1 100755 --- a/main.py +++ b/main.py @@ -129,6 +129,10 @@ def process_whisper(nick, msg, mapserv): elif broken_string[0] == "!help": # Sends help information + if int(user.get('accesslevel')) < 0: + mapserv.sendall(whisper(nick, "You seem to be a bood guy, please don't harm me anymore.")) + return + if len(broken_string) == 1: mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) @@ -138,6 +142,20 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) + if int(user.get('accesslevel')) >= 5: + mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! + mapserv.sendall(whisper(nick, "Use !add to tell me, I should trade stuff for you:")) + mapserv.sendall(whisper(nick, "e.g. !add 10 1000 IronOre would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) + mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) + elif int(user.get('accesslevel')) == 20: + mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) + mapserv.sendall(whisper(nick, "!listusers lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) + mapserv.sendall(whisper(nick, "!setslots sets the name to use only the given ")) + mapserv.sendall(whisper(nick, "!setaccess sets access level for the player. -1 is blocked, 5 is seller and 20 is admin" )) + mapserv.sendall(whisper(nick, "!adduser , whereas level should be 5 for seller, 20 for admin.")) + + + elif len(broken_string) == 2: if broken_string[1] == '!buy': mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) -- cgit v1.2.3-70-g09d2 From 4d1a0ffba73b0c21a6529e9387ade801cb6d2c7b Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:23:21 +0100 Subject: Clean up some help code. --- main.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/main.py b/main.py index 7e2e4e1..965b8ce 100755 --- a/main.py +++ b/main.py @@ -129,10 +129,6 @@ def process_whisper(nick, msg, mapserv): elif broken_string[0] == "!help": # Sends help information - if int(user.get('accesslevel')) < 0: - mapserv.sendall(whisper(nick, "You seem to be a bood guy, please don't harm me anymore.")) - return - if len(broken_string) == 1: mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) @@ -145,7 +141,7 @@ def process_whisper(nick, msg, mapserv): if int(user.get('accesslevel')) >= 5: mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! mapserv.sendall(whisper(nick, "Use !add to tell me, I should trade stuff for you:")) - mapserv.sendall(whisper(nick, "e.g. !add 10 1000 IronOre would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) + mapserv.sendall(whisper(nick, "e.g. !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) elif int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) -- cgit v1.2.3-70-g09d2 From 73691da56f541ea1730043d0e654d97414dcb92a Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:47:40 +0100 Subject: Inventory/Money Check. --- main.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/main.py b/main.py index 965b8ce..8659967 100755 --- a/main.py +++ b/main.py @@ -801,6 +801,31 @@ def main(): logging.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) + + # Check the inventory state and the amount of money match the information saved. + amount = -1 + test_node = player_node.inventory + for item in test_node: + amount = test_node[item].amount + for elem in sale_tree.root: + if int(elem.get('itemId')) == test_node[item].itemId \ + and int(elem.get('amount')) >= amount: + amount -= int(elem.get('amount')) + + if amount == 0: + del test_node[item] + + if amount < 0: + logging.info("Server and client inventory out of sync.") + exit(0) + + total_money = 0 + for user in user_tree: + total_money += int(user.get('money')) + + if total_money > player_node.MONEY: + logging.info("Server and client money out of sync.") + exit(0) elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) -- cgit v1.2.3-70-g09d2 From 3bb4e2bd0100e353e6cffb92202e2d60c14c19a1 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:48:45 +0100 Subject: tab error --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 8659967..cc243ca 100755 --- a/main.py +++ b/main.py @@ -805,7 +805,7 @@ def main(): # Check the inventory state and the amount of money match the information saved. amount = -1 test_node = player_node.inventory - for item in test_node: + for item in test_node: amount = test_node[item].amount for elem in sale_tree.root: if int(elem.get('itemId')) == test_node[item].itemId \ -- cgit v1.2.3-70-g09d2 From b9e937fa64f05670f590d7bfc67d537e4834f0ab Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:59:51 +0100 Subject: Revert "tab error" This reverts commit 3bb4e2bd0100e353e6cffb92202e2d60c14c19a1. --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index cc243ca..8659967 100755 --- a/main.py +++ b/main.py @@ -805,7 +805,7 @@ def main(): # Check the inventory state and the amount of money match the information saved. amount = -1 test_node = player_node.inventory - for item in test_node: + for item in test_node: amount = test_node[item].amount for elem in sale_tree.root: if int(elem.get('itemId')) == test_node[item].itemId \ -- cgit v1.2.3-70-g09d2 From 2fdc157430b64a7d894fe787dd09b1810b95b96b Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 11:59:58 +0100 Subject: Revert "Inventory/Money Check." This reverts commit 73691da56f541ea1730043d0e654d97414dcb92a. --- main.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/main.py b/main.py index 8659967..965b8ce 100755 --- a/main.py +++ b/main.py @@ -801,31 +801,6 @@ def main(): logging.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) - - # Check the inventory state and the amount of money match the information saved. - amount = -1 - test_node = player_node.inventory - for item in test_node: - amount = test_node[item].amount - for elem in sale_tree.root: - if int(elem.get('itemId')) == test_node[item].itemId \ - and int(elem.get('amount')) >= amount: - amount -= int(elem.get('amount')) - - if amount == 0: - del test_node[item] - - if amount < 0: - logging.info("Server and client inventory out of sync.") - exit(0) - - total_money = 0 - for user in user_tree: - total_money += int(user.get('money')) - - if total_money > player_node.MONEY: - logging.info("Server and client money out of sync.") - exit(0) elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) -- cgit v1.2.3-70-g09d2 From c38c4a477833507e04b1779a11a45f0c28cb60cc Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 12:18:04 +0100 Subject: Fixed logic for checking money/inventory state. --- main.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/main.py b/main.py index 965b8ce..07dd749 100755 --- a/main.py +++ b/main.py @@ -802,6 +802,30 @@ def main(): ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) + # Check the inventory state and the amount of money match the information saved. + test_node = player_node.inventory + for elem in sale_tree.root: + item_found = False + for item in test_node: + if int(elem.get('itemId')) == test_node[item].itemId \ + and int(elem.get('amount')) <= test_node[item].amount: + test_node[item].amount -= int(elem.get('amount')) + if test_node[item].amount == 0: + del test_node[item] + item_found = True + + if not item_found: + logging.info("Server and client inventory out of sync.") + exit(0) + + total_money = 0 + for user in user_tree: + total_money += int(user.get('money')) + + if total_money > player_node.MONEY: + logging.info("Server and client money out of sync.") + exit(0) + elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) logging.info("Trade request: " + name) -- cgit v1.2.3-70-g09d2 From 2cb97b9da0caf0e44134f483b882d54570405f75 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 13:06:51 +0100 Subject: Add pretty xml printing using xml.dom.minidom. --- tradey.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tradey.py b/tradey.py index 8ec6c6b..b70fd24 100644 --- a/tradey.py +++ b/tradey.py @@ -8,6 +8,7 @@ """ import time import os +import xml.dom.minidom from subprocess import call from xml.etree.ElementTree import * @@ -43,8 +44,10 @@ class UserTree: def save(self): # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/user.xml") + f = open('data/user.xml', 'w') + dom = xml.dom.minidom.parseString(tostring(self.root)) + f.write(str(dom.toprettyxml(' '))) + f.close() class ItemTree: def __init__(self): @@ -94,8 +97,10 @@ class ItemTree: def save(self): # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/sale.xml") + f = open('data/sale.xml', 'w') + dom = xml.dom.minidom.parseString(tostring(self.root)) + f.write(str(dom.toprettyxml(' '))) + f.close() def saveData(commitmessage = "commit"): # This assumes the current working directory is the tradey directory. -- cgit v1.2.3-70-g09d2 From 652145ff00785401ff7ca70e02fa6760f2b8f438 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 13:29:30 +0100 Subject: A few fixes, now runs without a crash! --- main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 07dd749..0929005 100755 --- a/main.py +++ b/main.py @@ -609,9 +609,8 @@ def main(): slot = packet.read_int8() packet.skip(1) logging.info("Character information recieved:") - logging.info("Name: %s, Id: %s, EXP: %s, MONEY: %s, HP: %s/%s, MP: %s/%s, LEVEL: %s", \ - player_node.name, player_node.id, player_node.EXP, player_node.MONEY, player_node.HP, \ - player_node.MAX_HP, player_node.MP, player_node.MAX_MP, player_node.LEVEL) + logging.info("Name: %s, Id: %s, EXP: %s, MONEY: %s", \ + player_node.name, player_node.id, player_node.EXP, player_node.MONEY) if slot == character: break @@ -813,18 +812,19 @@ def main(): if test_node[item].amount == 0: del test_node[item] item_found = True + break if not item_found: logging.info("Server and client inventory out of sync.") exit(0) total_money = 0 - for user in user_tree: + for user in user_tree.root: total_money += int(user.get('money')) - if total_money > player_node.MONEY: - logging.info("Server and client money out of sync.") - exit(0) + if total_money > player_node.MONEY: + logging.info("Server and client money out of sync.") + exit(0) elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) -- cgit v1.2.3-70-g09d2 From 81d0ec4e7199e0329a9c449f76bc3847dde20d5b Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 14:00:01 +0100 Subject: Edit some of the help. --- main.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 0929005..42f5e5b 100755 --- a/main.py +++ b/main.py @@ -145,12 +145,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) elif int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) - mapserv.sendall(whisper(nick, "!listusers lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) - mapserv.sendall(whisper(nick, "!setslots sets the name to use only the given ")) - mapserv.sendall(whisper(nick, "!setaccess sets access level for the player. -1 is blocked, 5 is seller and 20 is admin" )) - mapserv.sendall(whisper(nick, "!adduser , whereas level should be 5 for seller, 20 for admin.")) - - + mapserv.sendall(whisper(nick, "You also have access to the following commands: !listusers, !setslots , !setaccess , !adduser ")) elif len(broken_string) == 2: if broken_string[1] == '!buy': @@ -171,7 +166,14 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) elif broken_string[1] == '!getback': mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) - + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!listusers': + mapserv.sendall(whisper(nick, "!listusers - Lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!adduser': + mapserv.sendall(whisper(nick, "!adduser - Add a user to the bot, a seller should be added with access level 5.")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setslots': + mapserv.sendall(whisper(nick, "!setslots - Sets the number of slots available to a given user.")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setaccess': + mapserv.sendall(whisper(nick, "!setaccess - Sets access level for the player: -1 is blocked, 5 is seller and 20 is admin" )) elif msg == "!money": # Trades any money earned through item sales. if user == -10: -- cgit v1.2.3-70-g09d2 From cd9ac58f45f5e29b99917269f48eb7098aee7e6f Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 15:05:41 +0100 Subject: More cleanup. --- main.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 42f5e5b..db30be3 100755 --- a/main.py +++ b/main.py @@ -6,13 +6,6 @@ tradey, a package, which implements an Automated Market Bot for "The Mana World" a 2D MMORPG. - - Currently permissions are defined as: -1 (blocked), 0 (normal user), 5 (seller), 20 (admin). - - An item will only be listed for a period of one week, and can be relisted - for 3 weeks. - - If a Trade in uncompleted within 5 minutes of a Trade Request, it is cancelled - to prevent any disruptions to service. - - The Bot supports the manaplus "right click and buy" feature; if an item is listed - twice for the same price, the first shown in the list will be bought (i.e. the one added earlier). """ import logging @@ -21,15 +14,13 @@ import sys import time import string - - -from being import * try: import config except: print "no config file found. please move config.py.template to config.py and edit to your needs!" exit(0); +from being import * from net.packet import * from net.protocol import * from net.packet_out import * @@ -680,8 +671,7 @@ def main(): nick = packet.read_string(24) message = packet.read_raw_string(msg_len) logging.info("Whisper: " + nick + ": " + message) - if nick != "guild": - process_whisper(nick, utils.remove_colors(message), mapserv) + process_whisper(nick, utils.remove_colors(message), mapserv) elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): stat_type = packet.read_int16() -- cgit v1.2.3-70-g09d2 From 23b900a3359510a3dba34e210bd8ab9b0965e6d5 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 22 Aug 2011 15:29:24 +0100 Subject: Pretty horrible bug, was altering the inventory state when checking. --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index db30be3..88fe85f 100755 --- a/main.py +++ b/main.py @@ -794,7 +794,7 @@ def main(): player_node.inventory[item].itemId, item, player_node.inventory[item].amount) # Check the inventory state and the amount of money match the information saved. - test_node = player_node.inventory + test_node = player_node.inventory.copy() for elem in sale_tree.root: item_found = False for item in test_node: -- cgit v1.2.3-70-g09d2 From 1404493735325ce94539fa939567933255412c02 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Tue, 23 Aug 2011 10:15:16 +0200 Subject: adding data_template and README file --- README | 6 + data_template/items.xml | 5540 +++++++++++++++++++++++++++++++++++++++ data_template/logs/activity.log | 0 data_template/logs/sale.log | 0 data_template/sale.xml | 1 + data_template/user.xml | 1 + 6 files changed, 5548 insertions(+) create mode 100644 README create mode 100644 data_template/items.xml create mode 100644 data_template/logs/activity.log create mode 100644 data_template/logs/sale.log create mode 100644 data_template/sale.xml create mode 100644 data_template/user.xml diff --git a/README b/README new file mode 100644 index 0000000..bfdb8f7 --- /dev/null +++ b/README @@ -0,0 +1,6 @@ + +To get your own copy of tradey: + +cp config.py.template config.py +cp data_template data/ +cd data git init diff --git a/data_template/items.xml b/data_template/items.xml new file mode 100644 index 0000000..1656c73 --- /dev/null +++ b/data_template/items.xml @@ -0,0 +1,5540 @@ + + + + + + + + hairstyles/hairstyle01.xml + + + hairstyles/hairstyle02.xml + + + hairstyles/hairstyle03.xml + + + hairstyles/hairstyle04.xml + + + hairstyles/hairstyle05.xml + + + hairstyles/hairstyle06.xml + + + hairstyles/hairstyle07.xml + + + hairstyles/hairstyle08.xml + + + hairstyles/hairstyle09.xml + + + hairstyles/hairstyle10.xml + + + hairstyles/hairstyle11.xml + + + hairstyles/hairstyle12.xml + + + hairstyles/hairstyle13.xml + + + hairstyles/hairstyle14.xml + + + hairstyles/hairstyle15.xml + + + hairstyles/hairstyle16.xml + + + hairstyles/hairstyle17.xml + + + hairstyles/hairstyle18.xml + + + + + player_male_base.xml + player_female_base.xml + + + + + + + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + weapon-scythe.xml + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-fist.xml + + + weapon-staff.xml + + + + + + + + + + + + + + + + equipment/head/santahat.xml + + + + + + + + + + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/short-sword-hit1.ogg + + + weapon-dagger.xml + weapons/knives/sharpknife-miss1.ogg + + + equipment/chest/leather-male.xml|#573a26,9e7654,d3b79e,ffffff;#b96b3d,fbf5f1 + equipment/chest/leather-female.xml|#412300,603100,8d4900;#ffff00 + + + equipment/head/fancyhat.xml + + + equipment/head/minershat.xml + + + + + equipment/feet/boots-male.xml|#623a34,f0c2b4 + equipment/feet/boots-female.xml|#623a34,f0c2b4 + + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + equipment/hands/generic-male.xml|#202020,505050 + equipment/hands/generic-female.xml|#202020,505050 + + + equipment/hands/generic-male.xml|#4e2e18,c8752f + equipment/hands/generic-female.xml|#4e2e18,c8752f + + + + + + weapon-dagger.xml + + + + + + + + + equipment/head/standardheadband.xml|#563f25,99784c,d8bd86,ffffff + + + equipment/head/silkheadband.xml + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + equipment/chest/leather-male.xml|#443c21,85794a,beb590,ffffff;#824035,d6a19a + equipment/chest/leather-female.xml|#251e06,443c21,71653b,a0945e;#b6574a + + + + + + weapon-axe-blacksmith.xml + + + + + + + + + + + + + + + equipment/hands/generic-male.xml|#202020,c0c0c0,ffffff,ffffff + equipment/hands/generic-female.xml|#202020,c0c0c0,ffffff,ffffff + + + equipment/chest/tnecksweater-male.xml|#a4b2b2,ffffff + equipment/chest/tnecksweater-female.xml|#a4b2b2,ffffff + + + + + + + + weapon-dagger.xml + + + weapon-dagger.xml + + + + + + + + + + weapon-dagger.xml + + + + + + + + + equipment/legs/shorts-male.xml|#a4b2b2,ffffff + equipment/legs/shorts-female.xml|#a4b2b2,ffffff + + + + + weapon-sword-sword.xml + + + + + + + + + + + + equipment/legs/shorts-male.xml|#255367,266c84,68b0c5,ffffff + equipment/legs/shorts-female.xml|#255367,266c84,68b0c5,ffffff + + + + + + + equipment/head/pumpkinhelmet.xml + + + equipment/head/axehat.xml + + + equipment/head/piratehat.xml + + + equipment/head/goggles.xml|#787878,f7f7f7 + + + equipment/head/goggles.xml|#783c00,ff973b + + + equipment/head/circlet.xml + + + equipment/head/eyepatch.xml + + + equipment/head/bandana.xml + + + weapon-scythe.xml + + + equipment/chest/vnecksweater-male.xml|#a4b2b2,ffffff + equipment/chest/vnecksweater-female.xml|#a4b2b2,ffffff + + + equipment/chest/chainmail-male.xml + equipment/chest/chainmail-female.xml + + + equipment/chest/lightplatemail-male.xml|#ddeeff + equipment/chest/lightplatemail-female.xml|#ddeeff + + + equipment/head/tophat.xml + + + equipment/head/funkywinter.xml + + + equipment/head/mushroom.xml + + + equipment/head/shroom.xml + + + + equipment/legs/skirt.xml|#a4b2b2,ffffff + + + equipment/head/xmaself.xml + + + equipment/head/mask.xml + + + + equipment/head/warlordhelm.xml + + + equipment/head/knighthelm.xml + + + equipment/head/infantryhelm.xml + + + equipment/head/crusadehelm.xml + + + + + equipment/legs/chaps-male.xml + equipment/legs/chaps-female.xml + + + equipment/head/cowboywhite.xml + + + equipment/head/cowboyblack.xml + + + equipment/chest/lightplatemail-male.xml|#573f10,9c8226,d3c04b,ffffff + equipment/chest/lightplatemail-female.xml|#573f10,9c8226,d3c04b,ffffff + + + equipment/head/crown.xml + + + equipment/head/devcap.xml|#9999ff + + + equipment/head/devcap.xml|#9999ff + + + equipment/chest/sorcerer-robe-male.xml|#5e7480,f1ffff,ffffff;#2554c7 + equipment/chest/sorcerer-robe-female.xml|#5e7480,f1ffff,ffffff;#2554c7 + + + equipment/chest/sorcerer-robe-male.xml|#000000;#2554c7 + equipment/chest/sorcerer-robe-female.xml|#000000;#2554c7 + + + equipment/chest/robe-male.xml|#5e7480,f1ffff,ffffff + equipment/chest/robe-female.xml|#5e7480,f1ffff,ffffff + + + equipment/chest/robe-male.xml|#000000 + equipment/chest/robe-female.xml|#000000 + + + equipment/chest/robe-male.xml|#804000 + equipment/chest/robe-female.xml|#804000 + + + equipment/head/cap.xml|#d94800 + + + equipment/feet/furboots-male.xml + equipment/feet/furboots-female.xml + + + equipment/head/serf.xml + + + + equipment/chest/warlordplate-male.xml + equipment/chest/warlordplate-female.xml + + + equipment/chest/warlordplate-male.xml|#573f10,9c8226,d3c04b,ffffff + equipment/chest/warlordplate-female.xml|#573f10,9c8226,d3c04b,ffffff + + + + + + + + + + + + + + + + + + equipment/head/gradcap.xml + + + + + equipment/head/nohmask.xml + + + equipment/head/demonmask.xml + + + + + + + + + + + equipment/chest/tanktop-male.xml|#a4b2b2,ffffff + equipment/chest/tanktop-female.xml|#a4b2b2,ffffff + + + equipment/chest/shorttanktop-male.xml|#a4b2b2,ffffff + equipment/chest/shorttanktop-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + equipment/chest/robe-male.xml|#ffffff + equipment/chest/robe-female.xml|#ffffff + + + equipment/head/highpriest-crown.xml + + + equipment/head/monster-skull-helm.xml + + + equipment/head/deserthat.xml|#ffffff + + + equipment/head/standardheadband.xml|#a4b2b2,ffffff + + + equipment/head/gmcap.xml|#bf0e08 + + + equipment/chest/robe-male.xml|#e40a0a + equipment/chest/robe-female.xml|#e40a0a + + + + + + + equipment/legs/assassin-male.xml + equipment/legs/assassin-female.xml + + + + + equipment/feet/boots-male.xml|#212121 + equipment/feet/boots-female.xml|#212121 + + + equipment/feet/boots-male.xml|#a4b2b2,ffffff + equipment/feet/boots-female.xml|#a4b2b2,ffffff + + + + + + + + equipment/hands/generic-male.xml|#a4b2b2,ffffff + equipment/hands/generic-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + equipment/head/pinkiehat.xml + + + equipment/head/fluffyhat.xml + + + + + equipment/chest/assassin-male.xml + equipment/chest/assassin-female.xml + + + equipment/hands/assassin-male.xml + equipment/hands/assassin-female.xml + + + equipment/feet/assassin-boots-male.xml + equipment/feet/assassin-boots-female.xml + + + weapon-staff.xml + + + equipment/head/paladinhelm.xml + + + equipment/head/overlordhelm.xml + + + equipment/head/desert-helmet.xml + + + + + equipment/head/sailor-hat.xml + + + equipment/head/captain-hat.xml + + + equipment/head/terranitehelm.xml + + + equipment/chest/terranite-male.xml + equipment/chest/terranite-female.xml + + + equipment/legs/terranite-male.xml + equipment/legs/terranite-female.xml + + + equipment/head/guyfawkes.xml + + + equipment/head/fairy_hat.xml + + + equipment/legs/miniskirt-male.xml|#a4b2b2,ffffff + equipment/legs/miniskirt-female.xml|#a4b2b2,ffffff + + + + + + + + + + + + equipment/head/witch-doctor-mask.xml + + + equipment/chest/forest-armor-male.xml + equipment/chest/forest-armor-female.xml + + + equipment/chest/valentine-dress.xml|#bf0e08 + + + + + + + + + + equipment/chest/leather-male.xml|#573a26,c9866b,d3b79e,ffffff;#b96b3d,fbf5f1 + equipment/chest/leather-female.xml|#412300,c9866b,8d4900;#ffff00 + + + equipment/feet/bromenalboots-male.xml + equipment/feet/bromenalboots-female.xml + + + equipment/chest/bromenalchest-male.xml|#fbf5e9 + equipment/chest/bromenalchest-female.xml|#fbf5e9 + + + equipment/hands/bromenalgloves-male.xml + equipment/hands/bromenalgloves-female.xml + + + equipment/head/bromenalhelmet.xml + + + equipment/legs/bromenallegs-male.xml + equipment/legs/bromenallegs-female.xml + + + + equipment/chest/sorcerer-robe-male.xml|#ffffff + equipment/chest/sorcerer-robe-female.xml|#ffffff + + + + equipment/head/bowler-hat-brown.xml + + + equipment/head/pinkie-helmet.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + weapon-bow.xml + weapons/bows/bow_shoot_1.ogg + + + weapon-dagger.xml + + + equipment/chest/cotton-male.xml|#a4b2b2,ffffff + equipment/chest/cotton-female.xml|#a4b2b2,ffffff + + + equipment/head/rangerhat.xml + + + equipment/head/antlerhat.xml + + + equipment/head/christmastree.xml + + + equipment/head/santabeardhat.xml + + + + + + + + + + equipment/head/bunnyears.xml + + + weapon-dagger.xml + weapons/swords/short-sword-miss1.ogg + weapons/swords/sabre-hit1.ogg + + + equipment/head/mouboohead.xml + + + equipment/head/catears.xml|#774444;#777777 + + + equipment/head/paperbag.xml + + + equipment/head/moubootaurhead.xml + + + equipment/head/parsley-earplugs.xml + + + equipment/head/skullmask.xml + + + + + + + + + + + + + + + + + + + + + + + equipment/head/snowgoggles.xml + + + + + + equipment/override/skeleton.xml + graphics/particles/wisp.particle.xml + + + + + equipment/head/heart-glasses.xml + + + + + + + + + + equipment/head/rabbit-ears.xml|#ffffff + + + equipment/head/eggshell.xml + + + + + equipment/head/operamask.xml + + + equipment/head/jestermask.xml + + + equipment/head/witch-hat.xml + + + equipment/head/goblin-mask.xml + + + + + + + + + equipment/chest/cotton-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/cotton-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/cotton-male.xml|#115511,22aa22,99dd99 + equipment/chest/cotton-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/cotton-male.xml|#222255,6666ff + equipment/chest/cotton-female.xml|#222255,6666ff + + + equipment/chest/cotton-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/cotton-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/cotton-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/cotton-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/cotton-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/cotton-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/cotton-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/cotton-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/cotton-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/cotton-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/cotton-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/cotton-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/cotton-male.xml|#104010,208020,30c030 + equipment/chest/cotton-female.xml|#104010,208020,30c030 + + + + equipment/chest/vnecksweater-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/vnecksweater-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/vnecksweater-male.xml|#115511,22aa22,99dd99 + equipment/chest/vnecksweater-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/vnecksweater-male.xml|#222255,6666ff + equipment/chest/vnecksweater-female.xml|#222255,6666ff + + + equipment/chest/vnecksweater-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/vnecksweater-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/vnecksweater-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/vnecksweater-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/vnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/vnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/vnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/vnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/vnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/vnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/vnecksweater-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/vnecksweater-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/vnecksweater-male.xml|#104010,208020,30c030 + equipment/chest/vnecksweater-female.xml|#104010,208020,30c030 + + + + equipment/chest/tnecksweater-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/tnecksweater-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/tnecksweater-male.xml|#115511,22aa22,99dd99 + equipment/chest/tnecksweater-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/tnecksweater-male.xml|#222255,6666ff + equipment/chest/tnecksweater-female.xml|#222255,6666ff + + + equipment/chest/tnecksweater-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/tnecksweater-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/tnecksweater-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/tnecksweater-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/tnecksweater-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/tnecksweater-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/tnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/tnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/tnecksweater-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/tnecksweater-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/tnecksweater-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/tnecksweater-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/tnecksweater-male.xml|#104010,208020,30c030 + equipment/chest/tnecksweater-female.xml|#104010,208020,30c030 + + + + equipment/chest/robe-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/robe-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/robe-male.xml|#115511,22aa22,99dd99 + equipment/chest/robe-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/robe-male.xml|#222255,6666ff + equipment/chest/robe-female.xml|#222255,6666ff + + + equipment/chest/robe-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/robe-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/robe-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/robe-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/robe-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/robe-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/robe-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/robe-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/robe-male.xml|#104010,208020,30c030 + equipment/chest/robe-female.xml|#104010,208020,30c030 + + + + equipment/chest/tanktop-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/tanktop-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/tanktop-male.xml|#115511,22aa22,99dd99 + equipment/chest/tanktop-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/tanktop-male.xml|#222255,6666ff + equipment/chest/tanktop-female.xml|#222255,6666ff + + + equipment/chest/tanktop-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/tanktop-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/tanktop-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/tanktop-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/tanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/tanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/tanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/tanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/tanktop-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/tanktop-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/tanktop-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/tanktop-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/tanktop-male.xml|#104010,208020,30c030 + equipment/chest/tanktop-female.xml|#104010,208020,30c030 + + + + equipment/legs/skirt.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/skirt.xml|#115511,22aa22,99dd99 + + + equipment/legs/skirt.xml|#222255,6666ff + + + equipment/legs/skirt.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/skirt.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/skirt.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/skirt.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/skirt.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/skirt.xml|#4f0a76,8010c0,d699f7 + + + equipment/legs/skirt.xml|#104010,208020,30c030 + + + + equipment/legs/shorts-male.xml|#580000,a40000,c02020,ff6060 + equipment/legs/shorts-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/shorts-male.xml|#115511,22aa22,99dd99 + equipment/legs/shorts-female.xml|#115511,22aa22,99dd99 + + + equipment/legs/shorts-male.xml|#222255,6666ff + equipment/legs/shorts-female.xml|#222255,6666ff + + + equipment/legs/shorts-male.xml|#846211,dab333,fffb93,ffffff + equipment/legs/shorts-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/shorts-male.xml|#16486e,498ec5,e4f2fc + equipment/legs/shorts-female.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/shorts-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/legs/shorts-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/shorts-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/legs/shorts-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/shorts-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/legs/shorts-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/shorts-male.xml|#520a7b,8c23c7,ca87ef + equipment/legs/shorts-female.xml|#520a7b,8c23c7,ca87ef + + + equipment/legs/shorts-male.xml|#104010,208020,30c030 + equipment/legs/shorts-female.xml|#104010,208020,30c030 + + + + equipment/chest/shorttanktop-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/shorttanktop-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/shorttanktop-male.xml|#115511,22aa22,99dd99 + equipment/chest/shorttanktop-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/shorttanktop-male.xml|#222255,6666ff + equipment/chest/shorttanktop-female.xml|#222255,6666ff + + + equipment/chest/shorttanktop-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/shorttanktop-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/shorttanktop-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/shorttanktop-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/shorttanktop-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/shorttanktop-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/shorttanktop-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/shorttanktop-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/shorttanktop-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/shorttanktop-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/shorttanktop-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/shorttanktop-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/shorttanktop-male.xml|#104010,208020,30c030 + equipment/chest/shorttanktop-female.xml|#104010,208020,30c030 + + + + equipment/head/deserthat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/deserthat.xml|#115511,22aa22,99dd99 + + + equipment/head/deserthat.xml|#222255,6666ff + + + equipment/head/deserthat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/deserthat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/deserthat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/deserthat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/deserthat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/deserthat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/deserthat.xml|#104010,208020,30c030 + + + + equipment/head/standardheadband.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/standardheadband.xml|#115511,22aa22,99dd99 + + + equipment/head/standardheadband.xml|#222255,6666ff + + + equipment/head/standardheadband.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/standardheadband.xml|#16486e,498ec5,e4f2fc + + + equipment/head/standardheadband.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/standardheadband.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/standardheadband.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/standardheadband.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/standardheadband.xml|#104010,208020,30c030 + + + + equipment/feet/boots-male.xml|#580000,a40000,c02020,ff6060 + equipment/feet/boots-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/feet/boots-male.xml|#115511,22aa22,99dd99 + equipment/feet/boots-female.xml|#115511,22aa22,99dd99 + + + equipment/feet/boots-male.xml|#222255,6666ff + equipment/feet/boots-female.xml|#222255,6666ff + + + equipment/feet/boots-male.xml|#846211,dab333,fffb93,ffffff + equipment/feet/boots-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/feet/boots-male.xml|#16486e,498ec5,e4f2fc + equipment/feet/boots-female.xml|#16486e,498ec5,e4f2fc + + + equipment/feet/boots-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/feet/boots-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/feet/boots-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/feet/boots-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/feet/boots-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/feet/boots-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/feet/boots-male.xml|#4f0a76,8010c0,d699f7 + equipment/feet/boots-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/feet/boots-male.xml|#104010,208020,30c030 + equipment/feet/boots-female.xml|#104010,208020,30c030 + + + + equipment/hands/generic-male.xml|#580000,a40000,c02020,ff6060 + equipment/hands/generic-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/hands/generic-male.xml|#115511,22aa22,99dd99 + equipment/hands/generic-female.xml|#115511,22aa22,99dd99 + + + equipment/hands/generic-male.xml|#222255,6666ff + equipment/hands/generic-female.xml|#222255,6666ff + + + equipment/hands/generic-male.xml|#846211,dab333,fffb93,ffffff + equipment/hands/generic-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/hands/generic-male.xml|#16486e,498ec5,e4f2fc + equipment/hands/generic-female.xml|#16486e,498ec5,e4f2fc + + + equipment/hands/generic-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/hands/generic-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/hands/generic-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/hands/generic-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/hands/generic-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/hands/generic-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/hands/generic-male.xml|#4f0a76,8010c0,d699f7 + equipment/hands/generic-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/hands/generic-male.xml|#104010,208020,30c030 + equipment/hands/generic-female.xml|#104010,208020,30c030 + + + + equipment/legs/miniskirt-male.xml|#580000,a40000,c02020,ff6060 + equipment/legs/miniskirt-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/miniskirt-male.xml|#115511,22aa22,99dd99 + equipment/legs/miniskirt-female.xml|#115511,22aa22,99dd99 + + + equipment/legs/miniskirt-male.xml|#222255,6666ff + equipment/legs/miniskirt-female.xml|#222255,6666ff + + + equipment/legs/miniskirt-male.xml|#846211,dab333,fffb93,ffffff + equipment/legs/miniskirt-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/miniskirt-male.xml|#16486e,498ec5,e4f2fc + equipment/legs/miniskirt-female.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/miniskirt-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/legs/miniskirt-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/miniskirt-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/legs/miniskirt-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/miniskirt-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/legs/miniskirt-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/miniskirt-male.xml|#4f0a76,8010c0,d699f7 + equipment/legs/miniskirt-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/legs/miniskirt-male.xml|#104010,208020,30c030 + equipment/legs/miniskirt-female.xml|#104010,208020,30c030 + + + + + + equipment/head/rabbit-ears.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/rabbit-ears.xml|#115511,22aa22,99dd99 + + + equipment/head/rabbit-ears.xml|#222255,6666ff + + + equipment/head/rabbit-ears.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/rabbit-ears.xml|#16486e,498ec5,e4f2fc + + + equipment/head/rabbit-ears.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/rabbit-ears.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/rabbit-ears.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/rabbit-ears.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/rabbit-ears.xml|#104010,208020,30c030 + + + + equipment/head/wizard-hat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/wizard-hat.xml|#115511,22aa22,99dd99 + + + equipment/head/wizard-hat.xml|#222255,6666ff + + + equipment/head/wizard-hat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/wizard-hat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/wizard-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/wizard-hat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/wizard-hat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/wizard-hat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/wizard-hat.xml|#104010,208020,30c030 + + + + equipment/head/bowler-hat.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/bowler-hat.xml|#115511,22aa22,99dd99 + + + equipment/head/bowler-hat.xml|#222255,6666ff + + + equipment/head/bowler-hat.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/bowler-hat.xml|#16486e,498ec5,e4f2fc + + + equipment/head/bowler-hat.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/bowler-hat.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/bowler-hat.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/bowler-hat.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/bowler-hat.xml|#104010,208020,30c030 + + + + equipment/chest/sorcerer-robe-male.xml|#580000,a40000,c02020,ff6060 + equipment/chest/sorcerer-robe-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/chest/sorcerer-robe-male.xml|#115511,22aa22,99dd99 + equipment/chest/sorcerer-robe-female.xml|#115511,22aa22,99dd99 + + + equipment/chest/sorcerer-robe-male.xml|#222255,6666ff + equipment/chest/sorcerer-robe-female.xml|#222255,6666ff + + + equipment/chest/sorcerer-robe-male.xml|#846211,dab333,fffb93,ffffff + equipment/chest/sorcerer-robe-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/chest/sorcerer-robe-male.xml|#16486e,498ec5,e4f2fc + equipment/chest/sorcerer-robe-female.xml|#16486e,498ec5,e4f2fc + + + equipment/chest/sorcerer-robe-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/chest/sorcerer-robe-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/chest/sorcerer-robe-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/chest/sorcerer-robe-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/chest/sorcerer-robe-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/chest/sorcerer-robe-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/chest/sorcerer-robe-male.xml|#4f0a76,8010c0,d699f7 + equipment/chest/sorcerer-robe-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/chest/sorcerer-robe-male.xml|#104010,208020,30c030 + equipment/chest/sorcerer-robe-female.xml|#104010,208020,30c030 + + + + equipment/head/bowler-hat-brown.xml|#580000,a40000,c02020,ff6060 + + + equipment/head/bowler-hat-brown.xml|#115511,22aa22,99dd99 + + + equipment/head/bowler-hat-brown.xml|#222255,6666ff + + + equipment/head/bowler-hat-brown.xml|#846211,dab333,fffb93,ffffff + + + equipment/head/bowler-hat-brown.xml|#16486e,498ec5,e4f2fc + + + equipment/head/bowler-hat-brown.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/head/bowler-hat-brown.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/head/bowler-hat-brown.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/head/bowler-hat-brown.xml|#4f0a76,8010c0,d699f7 + + + equipment/head/bowler-hat-brown.xml|#104010,208020,30c030 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + equipment/head/candlehelmet.xml + + + + + + + + + equipment/head/yeti-mask.xml + + + equipment/head/wizard-hat.xml + + + + equipment/head/bowler-hat.xml + + + equipment/head/monocle.xml + + diff --git a/data_template/logs/activity.log b/data_template/logs/activity.log new file mode 100644 index 0000000..e69de29 diff --git a/data_template/logs/sale.log b/data_template/logs/sale.log new file mode 100644 index 0000000..e69de29 diff --git a/data_template/sale.xml b/data_template/sale.xml new file mode 100644 index 0000000..872fd3d --- /dev/null +++ b/data_template/sale.xml @@ -0,0 +1 @@ + diff --git a/data_template/user.xml b/data_template/user.xml new file mode 100644 index 0000000..7646199 --- /dev/null +++ b/data_template/user.xml @@ -0,0 +1 @@ + -- cgit v1.2.3-70-g09d2 From eac0a33f4862ebdff5ac8e00fb819dbe34422597 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Tue, 23 Aug 2011 21:18:58 +0100 Subject: Move inventory check to player.py and remove prettyprintxml() having looked at the output this produces on the server, it looks terrible. For some reason it's adding millions of spaces, not sure if the same thing was happening on my computer. --- main.py | 30 ++++++------------------------ player.py | 26 ++++++++++++++++++++++++++ tradey.py | 13 ++++--------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/main.py b/main.py index 88fe85f..9307031 100755 --- a/main.py +++ b/main.py @@ -793,30 +793,12 @@ def main(): ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) - # Check the inventory state and the amount of money match the information saved. - test_node = player_node.inventory.copy() - for elem in sale_tree.root: - item_found = False - for item in test_node: - if int(elem.get('itemId')) == test_node[item].itemId \ - and int(elem.get('amount')) <= test_node[item].amount: - test_node[item].amount -= int(elem.get('amount')) - if test_node[item].amount == 0: - del test_node[item] - item_found = True - break - - if not item_found: - logging.info("Server and client inventory out of sync.") - exit(0) - - total_money = 0 - for user in user_tree.root: - total_money += int(user.get('money')) - - if total_money > player_node.MONEY: - logging.info("Server and client money out of sync.") - exit(0) + isclean = player_node.check_inventory(user_tree, sale_tree) + if isclean: + logging.info(isclean) + exit(0) + else: + logging.info("Inventory Check Passed.") elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) diff --git a/player.py b/player.py index 2e3eafa..6277837 100644 --- a/player.py +++ b/player.py @@ -38,5 +38,31 @@ class Player: return item return -10 # Not found - bug somewhere! + def check_inventory(self, user_tree, sale_tree): + # Check the inventory state. + test_node = self.inventory.copy() + for elem in sale_tree.root: + item_found = False + for item in test_node: + if int(elem.get('itemId')) == test_node[item].itemId \ + and int(elem.get('amount')) <= test_node[item].amount: + test_node[item].amount -= int(elem.get('amount')) + if test_node[item].amount == 0: + del test_node[item] + item_found = True + break + + if not item_found: + return "Server and client inventory out of sync." + + total_money = 0 + for user in user_tree.root: + total_money += int(user.get('money')) + + if total_money > self.MONEY: + return "Server and client money out of sync." + + return 0 + if __name__ == '__main__': print "Do not run this file directly. Run main.py" diff --git a/tradey.py b/tradey.py index b70fd24..8ec6c6b 100644 --- a/tradey.py +++ b/tradey.py @@ -8,7 +8,6 @@ """ import time import os -import xml.dom.minidom from subprocess import call from xml.etree.ElementTree import * @@ -44,10 +43,8 @@ class UserTree: def save(self): # Be sure to call save() after any changes to the tree. - f = open('data/user.xml', 'w') - dom = xml.dom.minidom.parseString(tostring(self.root)) - f.write(str(dom.toprettyxml(' '))) - f.close() + self.tree = ElementTree(self.root) + self.tree.write("data/user.xml") class ItemTree: def __init__(self): @@ -97,10 +94,8 @@ class ItemTree: def save(self): # Be sure to call save() after any changes to the tree. - f = open('data/sale.xml', 'w') - dom = xml.dom.minidom.parseString(tostring(self.root)) - f.write(str(dom.toprettyxml(' '))) - f.close() + self.tree = ElementTree(self.root) + self.tree.write("data/sale.xml") def saveData(commitmessage = "commit"): # This assumes the current working directory is the tradey directory. -- cgit v1.2.3-70-g09d2 From 2cd71629569e8501667f3243cad50b8aa3a2efd6 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Tue, 23 Aug 2011 22:42:42 +0100 Subject: Add some code to prevent problems with the !add command. Prevents the case where a person tries to add more than one piece of equiptment per slot. I also added some code to stop people adding items for free. --- main.py | 7 +++++++ utils.py | 2 ++ 2 files changed, 9 insertions(+) diff --git a/main.py b/main.py index 9307031..d275ffa 100755 --- a/main.py +++ b/main.py @@ -358,6 +358,13 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Item not found, check spelling.")) return + if amount > 1 and 'equip' in ItemDB.getItem(ItemDB.findId(item_name)).type: + mapserv.sendall(whisper(nick, "You can only add one piece of equiptment per slot.")) + return + elif price == 0: + mapserv.sendall(whisper(nick, "Nothing in life is free.")) + return + item = Item() item.player = nick item.get = 1 # 1 = get, 0 = give diff --git a/utils.py b/utils.py index 2e1d0e8..007bbcc 100644 --- a/utils.py +++ b/utils.py @@ -58,6 +58,8 @@ class ItemDB: item_struct.name = item.get('name') if item.get('weight'): item_struct.weight = item.get('weight') + if item.get('type'): + item_struct.type = item.get('type') item_struct.description = item.get('description') self.item_names[int(item.get('id'))] = item_struct -- cgit v1.2.3-70-g09d2 From 9c47ad7295661bf3577dfb48d92358f11cff3276 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 01:48:16 +0100 Subject: oops --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index d275ffa..8247c2c 100755 --- a/main.py +++ b/main.py @@ -358,7 +358,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Item not found, check spelling.")) return - if amount > 1 and 'equip' in ItemDB.getItem(ItemDB.findId(item_name)).type: + if amount > 1 and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equiptment per slot.")) return elif price == 0: -- cgit v1.2.3-70-g09d2 From 8029332e70ed71ca386c5f411f9ab138a26a53c5 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 10:25:03 +0100 Subject: Re-add pretty printing. The problem was caused by the xml file being read in indented, so once the prettyprintxml() was called it'd indent it again with a further 4 spaces. I wrote a little function to clean it before the prettyprintxml() call. --- tradey.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tradey.py b/tradey.py index 8ec6c6b..2de62ca 100644 --- a/tradey.py +++ b/tradey.py @@ -8,9 +8,20 @@ """ import time import os +import xml.dom.minidom from subprocess import call from xml.etree.ElementTree import * +def clean_xml(parse): + data = '' + pos_start = 0 + while parse.find('<', pos_start) != -1: + pos_start = parse.find('<', pos_start) + pos_end = parse.find('>', pos_start+1) + data += parse[pos_start:pos_end+1] + pos_start = pos_end + return data + class UserTree: def __init__(self): self.tree = ElementTree(file="data/user.xml") @@ -43,8 +54,10 @@ class UserTree: def save(self): # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/user.xml") + f = open('data/user.xml', 'w') + dom = xml.dom.minidom.parseString(clean_xml(tostring(self.root))) + f.write(dom.toprettyxml(' ')) + f.close() class ItemTree: def __init__(self): @@ -94,8 +107,10 @@ class ItemTree: def save(self): # Be sure to call save() after any changes to the tree. - self.tree = ElementTree(self.root) - self.tree.write("data/sale.xml") + f = open('data/sale.xml', 'w') + dom = xml.dom.minidom.parseString(clean_xml(tostring(self.root))) + f.write(dom.toprettyxml(' ')) + f.close() def saveData(commitmessage = "commit"): # This assumes the current working directory is the tradey directory. @@ -103,6 +118,5 @@ def saveData(commitmessage = "commit"): call(["git", "commit","-a", '-m "' + commitmessage + '"']) os.chdir("..") - if __name__ == '__main__': print "Do not run this file directly. Run main.py" -- cgit v1.2.3-70-g09d2 From 80d3df45dc769fe7e553caaea2ab938e94cbf07b Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 12:05:30 +0100 Subject: Further clean up, also fixed a tiny bug (wrong variable name). I move the remove item logic to player.py and have skipped some of inventory/equiptment information provided by the server. --- main.py | 36 ++++++++---------------------------- player.py | 6 ++++++ 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/main.py b/main.py index 8247c2c..89524e6 100755 --- a/main.py +++ b/main.py @@ -268,7 +268,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('stalls', str(slot)) mapserv.sendall(whisper(nick, "Slots changed: "+name+" "+str(slot))) - tradey.saveData("User: "+player_name+", Slots changed: "+str(slot)) + tradey.saveData("User: "+name+", Slots changed: "+str(slot)) user_tree.save() else: mapserv.sendall(whisper(nick, "Syntax incorrect.")) @@ -289,7 +289,6 @@ def process_whisper(nick, msg, mapserv): if (broken_string[1][0] == '-' and broken_string[1][1:].isdigit()) or broken_string[1].isdigit(): accesslevel = int(broken_string[1]) name = " ".join(broken_string[2:]) - user_info = user_tree.get_user(name) if user_info == -10: @@ -300,7 +299,7 @@ def process_whisper(nick, msg, mapserv): user_tree.get_user(name).set('accesslevel', str(accesslevel)) mapserv.sendall(whisper(nick, "Access level changed:"+name+ " ("+str(accesslevel)+").")) user_tree.save() - tradey.saveData("User: "+player_name+", Set Access Level: "+str(accesslevel)) + tradey.saveData("User: "+name+", Set Access Level: "+str(accesslevel)) else: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return @@ -736,12 +735,7 @@ def main(): item.index = packet.read_int16() - inventory_offset item.amount = packet.read_int16() item.itemId = packet.read_int16() - item.identified = packet.read_int8() - packet.read_int8() - item.refine = packet.read_int8() - packet.skip(8) - item.equipType = packet.read_int16() - item.itemType = packet.read_int8() + packet.skip(14) err = packet.read_int8() if err == 0: @@ -757,10 +751,7 @@ def main(): amount = packet.read_int16() logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) - if index in player_node.inventory: - player_node.inventory[index].amount -= amount - if player_node.inventory[index].amount == 0: - del player_node.inventory[index] + player_node.remove_item(index, amount) elif packet.is_type(SMSG_PLAYER_INVENTORY): player_node.inventory.clear() # Clear the inventory - incase of new index. @@ -770,11 +761,9 @@ def main(): item = Item() item.index = packet.read_int16() - inventory_offset item.itemId = packet.read_int16() - item.itemType = packet.read_int8() - item.identified = packet.read_int8() + packet.skip(2) item.amount = packet.read_int16() - item.arrow = packet.read_int16() - packet.skip(8) # Cards + packet.skip(10) player_node.inventory[item.index] = item elif packet.is_type(SMSG_PLAYER_EQUIPMENT): @@ -784,13 +773,7 @@ def main(): item = Item() item.index = packet.read_int16() - inventory_offset item.itemId = packet.read_int16() - item.itemType = packet.read_int8() - item.identified = packet.read_int8() - packet.skip(2) - item.equipType = packet.read_int16() - packet.skip(1) - item.refine = packet.read_int8() - packet.skip(8) + packet.skip(16) item.amount = 1 player_node.inventory[item.index] = item @@ -894,10 +877,7 @@ def main(): # If Trade item add successful - Remove the item from the inventory state. if index != 0-inventory_offset: # If it's not money logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) - if index in player_node.inventory: - player_node.inventory[index].amount -= amount - if player_node.inventory[index].amount == 0: - del player_node.inventory[index] + player_node.remove_item(index, amount) elif response == 1: logging.info("Trade item add response: Failed - player overweight.") diff --git a/player.py b/player.py index 6277837..6f602c5 100644 --- a/player.py +++ b/player.py @@ -38,6 +38,12 @@ class Player: return item return -10 # Not found - bug somewhere! + def remove_item(self, index, amount): + if index in self.inventory: + self.inventory[index].amount -= amount + if self.inventory[index].amount == 0: + del self.inventory[index] + def check_inventory(self, user_tree, sale_tree): # Check the inventory state. test_node = self.inventory.copy() -- cgit v1.2.3-70-g09d2 From cb31905b26679c5a0c9a7335943d0d1afe4547bc Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 15:17:15 +0100 Subject: Let a blocked user retrieve items/money. --- main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 89524e6..75afabf 100755 --- a/main.py +++ b/main.py @@ -44,8 +44,9 @@ def process_whisper(nick, msg, mapserv): if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. - mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) - return + if int(user.get("used_slots")) == 0 and int(user.get("money")) == 0: + mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) + return if msg == "!list": # Sends the list of items for sale. @@ -489,7 +490,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Syntax incorrect.")) return - if int(user.get("accesslevel")) < 5: + if int(user.get("accesslevel")) < 5 and int(user.get("accesslevel")) > 0: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return -- cgit v1.2.3-70-g09d2 From e7d3136463e4a52d6af47e36f21b6ad0303369e8 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 15:21:47 +0100 Subject: Prevent blocked users from buying items. --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index 75afabf..cda4edd 100755 --- a/main.py +++ b/main.py @@ -392,6 +392,10 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Syntax incorrect.")) return + if int(user.get("accesslevel")) == -1: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + if broken_string[1].isdigit() and broken_string[2].isdigit(): amount = int(broken_string[1]) uid = int(broken_string[2]) -- cgit v1.2.3-70-g09d2 From 6fd3838b814de0d51b2eb565c5cf80882a1e49be Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 18:26:20 +0100 Subject: teeny change --- utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils.py b/utils.py index 007bbcc..5940bc6 100644 --- a/utils.py +++ b/utils.py @@ -34,11 +34,11 @@ def encode_str(value, size): base = 94 start = 33 while value: - output += struct.pack(' Date: Wed, 24 Aug 2011 18:26:53 +0100 Subject: oops --- utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/utils.py b/utils.py index 5940bc6..364aeba 100644 --- a/utils.py +++ b/utils.py @@ -9,7 +9,6 @@ from xml.etree.ElementTree import ElementTree from player import Item -import struct import time import mutex import threading -- cgit v1.2.3-70-g09d2 From 309847f46d4ce1775b2539f650b1abf5739c7b6a Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 24 Aug 2011 19:27:30 +0200 Subject: improve blocked users --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index cda4edd..fe3c634 100755 --- a/main.py +++ b/main.py @@ -47,6 +47,10 @@ def process_whisper(nick, msg, mapserv): if int(user.get("used_slots")) == 0 and int(user.get("money")) == 0: mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) return + allowed_commands = ['!money', '!help', '!getback' ] + if not broken_string[0] in allowed_commands: + mapserv.sendall(whisper(nick, "Your access level has been set to blocked! If you feel this is in error, please contact .")) + mapserv.sendall(whisper(nick, "Though, you still can do the following: "+str(allowed_commands)) if msg == "!list": # Sends the list of items for sale. -- cgit v1.2.3-70-g09d2 From 8d7cc5ccafbdc24d2d94dbffeb963a93cb5b3869 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 24 Aug 2011 19:27:58 +0200 Subject: Revert "Prevent blocked users from buying items." This reverts commit e7d3136463e4a52d6af47e36f21b6ad0303369e8. --- main.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/main.py b/main.py index fe3c634..cd60c4a 100755 --- a/main.py +++ b/main.py @@ -396,10 +396,6 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Syntax incorrect.")) return - if int(user.get("accesslevel")) == -1: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return - if broken_string[1].isdigit() and broken_string[2].isdigit(): amount = int(broken_string[1]) uid = int(broken_string[2]) -- cgit v1.2.3-70-g09d2 From ce51681100e5ea18da7e2171f523296c28f0cda1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 24 Aug 2011 19:28:31 +0200 Subject: blocked users done right --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index cd60c4a..0adf113 100755 --- a/main.py +++ b/main.py @@ -51,6 +51,7 @@ def process_whisper(nick, msg, mapserv): if not broken_string[0] in allowed_commands: mapserv.sendall(whisper(nick, "Your access level has been set to blocked! If you feel this is in error, please contact .")) mapserv.sendall(whisper(nick, "Though, you still can do the following: "+str(allowed_commands)) + return if msg == "!list": # Sends the list of items for sale. -- cgit v1.2.3-70-g09d2 From cbd465195dd81fa36a1c7f86ca56b4a4e705351f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 24 Aug 2011 19:33:31 +0200 Subject: Adding !list for blocked users; introduce config.admin --- config.py.template | 1 + main.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/config.py.template b/config.py.template index df11a32..2d3155e 100644 --- a/config.py.template +++ b/config.py.template @@ -5,3 +5,4 @@ account = "" password = "" relist_time = 604800 # Time in seconds before an item needs to be relisted. character = 0 #slot character is in, 0 for first, 1 for second, 2 for third +admin = "Admin " diff --git a/main.py b/main.py index 0adf113..a14dbb2 100755 --- a/main.py +++ b/main.py @@ -45,11 +45,11 @@ def process_whisper(nick, msg, mapserv): if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. if int(user.get("used_slots")) == 0 and int(user.get("money")) == 0: - mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact .")) + mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact" + config.admin)) return - allowed_commands = ['!money', '!help', '!getback' ] + allowed_commands = ['!money', '!help', '!getback', '!info' ] if not broken_string[0] in allowed_commands: - mapserv.sendall(whisper(nick, "Your access level has been set to blocked! If you feel this is in error, please contact .")) + mapserv.sendall(whisper(nick, "Your access level has been set to blocked! If you feel this is in error, please contact" + config.admin)) mapserv.sendall(whisper(nick, "Though, you still can do the following: "+str(allowed_commands)) return -- cgit v1.2.3-70-g09d2 From 766e95b3c528193f920c68a0a33eaebba6fbb492 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 24 Aug 2011 19:34:13 +0200 Subject: ooops --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index a14dbb2..c4aa6b4 100755 --- a/main.py +++ b/main.py @@ -50,7 +50,7 @@ def process_whisper(nick, msg, mapserv): allowed_commands = ['!money', '!help', '!getback', '!info' ] if not broken_string[0] in allowed_commands: mapserv.sendall(whisper(nick, "Your access level has been set to blocked! If you feel this is in error, please contact" + config.admin)) - mapserv.sendall(whisper(nick, "Though, you still can do the following: "+str(allowed_commands)) + mapserv.sendall(whisper(nick, "Though, you still can do the following: "+str(allowed_commands))) return if msg == "!list": -- cgit v1.2.3-70-g09d2 From ad09c60c5f4668051331ff6db0203406a8118dc8 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 24 Aug 2011 18:45:39 +0100 Subject: Set a max on the price. --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index c4aa6b4..7799086 100755 --- a/main.py +++ b/main.py @@ -366,8 +366,8 @@ def process_whisper(nick, msg, mapserv): if amount > 1 and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equiptment per slot.")) return - elif price == 0: - mapserv.sendall(whisper(nick, "Nothing in life is free.")) + elif price == 0 or price > 50000000: + mapserv.sendall(whisper(nick, "Please use a valid price between 1-50000000gp.")) return item = Item() -- cgit v1.2.3-70-g09d2 From 182c9f5454157f09d8ea0ce4e24561f1e2060038 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 25 Aug 2011 23:37:45 +0100 Subject: Add a specific message for when a user adds money to a !add request. --- main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 7799086..124f433 100755 --- a/main.py +++ b/main.py @@ -843,8 +843,11 @@ def main(): if amount == trader_state.item.amount and item_id == trader_state.item.id: trader_state.complete = 1 mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + elif item_id == 0 and amount > 0: + mapserv.sendall(whisper(trader_state.item.player, "Why are you adding money?!?!")) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) else: - mapserv.sendall(whisper(trader_state.item.player, "Thats not the right item.")) + mapserv.sendall(whisper(trader_state.item.player, "That's not the right item.")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) elif trader_state.item.get == 0: # buy @@ -954,6 +957,7 @@ def main(): pass # On Disconnect/Exit + logging.info("Server disconnect.") shop_broadcaster.stop() mapserv.close() -- cgit v1.2.3-70-g09d2 From ffe3dc92e9f1fcac871e6d79e8fe3b7e57986d52 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 25 Aug 2011 23:48:40 +0100 Subject: Remove some surpurfulous code - the else: item_id == 0 would never be called. --- main.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 124f433..4d2ddcc 100755 --- a/main.py +++ b/main.py @@ -851,16 +851,13 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) elif trader_state.item.get == 0: # buy - if amount == trader_state.item.price * trader_state.item.amount and item_id == 0: + if item_id == 0 and amount == trader_state.item.price * trader_state.item.amount: mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) trader_state.complete = 1 elif item_id == 0 and amount != trader_state.item.price * trader_state.item.amount: trader_state.complete = 0 else: - if item_id == 0: - mapserv.sendall(whisper(trader_state.item.player, "Please verify you have the correct amount of money and try again.")) - else: - mapserv.sendall(whisper(trader_state.item.player, "Don't give me your itenz.")) + mapserv.sendall(whisper(trader_state.item.player, "Don't give me your itenz.")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) elif trader_state.money: # money -- cgit v1.2.3-70-g09d2 From 8dccb20d3ee6a5acd982913977ac0f5415fda588 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 26 Aug 2011 14:33:04 +0100 Subject: Make sure the ID provided is of the type wanted: default to player. Incase someone has the same name as an npc in the room. --- being.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/being.py b/being.py index e5d0b95..3c70616 100644 --- a/being.py +++ b/being.py @@ -21,9 +21,9 @@ class BeingManager: def __init__(self): self.container = {} - def findId(self, name): + def findId(self, name, type="player"): for i in self.container: - if self.container[i].name == name: + if self.container[i].name == name and self.container[i].type == type: return i return -10 -- cgit v1.2.3-70-g09d2 From 4b96c486d9cba72ec5fc3f4f15c4dbbd6ff13824 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 26 Aug 2011 14:50:51 +0100 Subject: Remove some no-longer needed variables. --- player.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/player.py b/player.py index 6f602c5..5501bba 100644 --- a/player.py +++ b/player.py @@ -20,14 +20,8 @@ class Player: self.x = 0 self.y = 0 - self.EXP_NEEDED = 0 self.EXP = 0 self.MONEY = 0 - self.LEVEL = 0 - self.HP = 0 - self.MaxHP = 0 - self.MP = 0 - self.MaxMP = 0 self.WEIGHT = 0 self.MaxWEIGHT = 0 -- cgit v1.2.3-70-g09d2 From a94f91a8b8a09910198eed8ab4407bc0c9ef66eb Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 28 Aug 2011 17:29:16 +0100 Subject: Add a message for an unrecognised command. --- main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.py b/main.py index 4d2ddcc..a43baad 100755 --- a/main.py +++ b/main.py @@ -530,6 +530,8 @@ def process_whisper(nick, msg, mapserv): else: mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) trader_state.reset() + else: + mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) def main(): logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -- cgit v1.2.3-70-g09d2 From a17c2faa9cf3ba50d4d1155870116e09e4cae3e1 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Tue, 30 Aug 2011 16:18:56 +0100 Subject: Respond "No" to incoming trade requests. --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index a43baad..ec4c3d0 100755 --- a/main.py +++ b/main.py @@ -801,6 +801,7 @@ def main(): elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) logging.info("Trade request: " + name) + mapserv.sendall(trade_respond(False)) elif packet.is_type(SMSG_TRADE_RESPONSE): response = packet.read_int8() -- cgit v1.2.3-70-g09d2 From e666fc6e9a6415f009065d3adaed39e0feb70b59 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Tue, 30 Aug 2011 23:55:37 +0100 Subject: remove unneeded line. --- utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils.py b/utils.py index 364aeba..d9d0319 100644 --- a/utils.py +++ b/utils.py @@ -48,8 +48,7 @@ class ItemDB: def __init__(self): print "Loading ItemDB" self.item_names = {} - self.itemdb_file = ElementTree() - self.itemdb_file.parse("data/items.xml") + self.itemdb_file = ElementTree(file="data/items.xml") for item in self.itemdb_file.getroot(): if item.get('id') > 500: -- cgit v1.2.3-70-g09d2 From 8cbc1eadd27e0bcb9f12ded7e1670509ee69fda3 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 31 Aug 2011 22:27:57 +0100 Subject: Minor help grammar corrections. --- main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index ec4c3d0..4fb53b7 100755 --- a/main.py +++ b/main.py @@ -130,15 +130,15 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find or , !buy , !add , !money, !relist , !info, !getback ")) mapserv.sendall(whisper(nick, "For a detailed description of each command, type !help e.g. !help !buy")) - mapserv.sendall(whisper(nick, "For example:- to purchase an item shown in the list as:")) + mapserv.sendall(whisper(nick, "For example to purchase an item shown in the list as:")) mapserv.sendall(whisper(nick, "[selling] [6] 5 [@@640|Iron Ore@@] for 1000gp each")) mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) if int(user.get('accesslevel')) >= 5: mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! - mapserv.sendall(whisper(nick, "Use !add to tell me, I should trade stuff for you:")) - mapserv.sendall(whisper(nick, "e.g. !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) + mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) + mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) elif int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) @@ -364,7 +364,7 @@ def process_whisper(nick, msg, mapserv): return if amount > 1 and 'equip' in ItemDB.getItem(item_id).type: - mapserv.sendall(whisper(nick, "You can only add one piece of equiptment per slot.")) + mapserv.sendall(whisper(nick, "You can only add one piece of equipment per slot.")) return elif price == 0 or price > 50000000: mapserv.sendall(whisper(nick, "Please use a valid price between 1-50000000gp.")) -- cgit v1.2.3-70-g09d2 From c547651e966c30aa564e9a4e5c53c83f11168128 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 31 Aug 2011 23:45:44 +0100 Subject: add command !tradestate --- main.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/main.py b/main.py index 4fb53b7..602afeb 100755 --- a/main.py +++ b/main.py @@ -223,6 +223,20 @@ def process_whisper(nick, msg, mapserv): if not items_found: mapserv.sendall(whisper(nick, "Item not found.")) + elif msg == '!tradestate': + # Admin command - return trade state. + if user == -10: + return + + if int(user.get("accesslevel")) != 20: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if not trader_state.Trading.test(): + mapserv.sendall(whisper(nick, "I'm busy with a trade.")) + else: + mapserv.sendall(whisper(nick, "I'm free.")) + elif msg == '!listusers': # Admin command - shows a list of all user. if user == -10: -- cgit v1.2.3-70-g09d2 From 891cc670cbd8da86c865aca602a73a8ee8372bd1 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 31 Aug 2011 23:59:02 +0100 Subject: ooops level 20 wasn't being shown --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 602afeb..2bafa40 100755 --- a/main.py +++ b/main.py @@ -140,7 +140,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) - elif int(user.get('accesslevel')) == 20: + if int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) mapserv.sendall(whisper(nick, "You also have access to the following commands: !listusers, !setslots , !setaccess , !adduser ")) -- cgit v1.2.3-70-g09d2 From 143f77c73df2ffdac65603db6a480d28d7861a5e Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 02:11:42 +0100 Subject: oops --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 2bafa40..64a3c2a 100755 --- a/main.py +++ b/main.py @@ -232,7 +232,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return - if not trader_state.Trading.test(): + if trader_state.Trading.test(): mapserv.sendall(whisper(nick, "I'm busy with a trade.")) else: mapserv.sendall(whisper(nick, "I'm free.")) -- cgit v1.2.3-70-g09d2 From 6122569f979456d41b81d25fa8d4d8037ef384ba Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 10:28:52 +0100 Subject: Teeny oversight with help - if a non-added player typed it, would of locked up. --- main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index 64a3c2a..ae98c54 100755 --- a/main.py +++ b/main.py @@ -135,14 +135,15 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "you would type /whisper ManaMarket !buy 1 6" )) mapserv.sendall(whisper(nick, "This will purchase one of item 6 (Iron Ore).")) - if int(user.get('accesslevel')) >= 5: - mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! - mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) - mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) - mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) - if int(user.get('accesslevel')) == 20: - mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) - mapserv.sendall(whisper(nick, "You also have access to the following commands: !listusers, !setslots , !setaccess , !adduser ")) + if user != -10: + if int(user.get('accesslevel')) >= 5: + mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! + mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) + mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) + mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) + if int(user.get('accesslevel')) == 20: + mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) + mapserv.sendall(whisper(nick, "You also have access to the following commands: !listusers, !setslots , !setaccess , !adduser ")) elif len(broken_string) == 2: if broken_string[1] == '!buy': -- cgit v1.2.3-70-g09d2 From 293331d4e2a843760a95b0fd690da0c035df6d5a Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 12:05:01 +0100 Subject: Add more logging to the item add process...and cancel on an unknown add response. --- main.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index ae98c54..0c3cd99 100755 --- a/main.py +++ b/main.py @@ -767,7 +767,7 @@ def main(): else: player_node.inventory[item.index] = item - logging.info("Picked up: %s, Amount: %s", ItemDB.getItem(item.itemId).name, str(item.amount)) + logging.info("Picked up: %s, Amount: %s, Index: %s", ItemDB.getItem(item.itemId).name, str(item.amount), str(item.index)) elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): index = packet.read_int16() - inventory_offset @@ -900,7 +900,7 @@ def main(): # If Trade item add successful - Remove the item from the inventory state. if index != 0-inventory_offset: # If it's not money - logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) player_node.remove_item(index, amount) elif response == 1: @@ -913,6 +913,11 @@ def main(): mapserv.sendall(whisper(trader_state.item.player, "You have no free slots.")) logging.info("Trade item add response: Failed - No free slots.") mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + else: + logging.info("Trade item add response: Failed - unknown reason.") + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "Sorry, a problem has occured.")) elif packet.is_type(SMSG_TRADE_OK): is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other -- cgit v1.2.3-70-g09d2 From 2caac2d05e8b40b13b4a03a1186d2ce8e1fc10df Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 13:30:04 +0100 Subject: oops quite a big one also had some duplication. --- main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 0c3cd99..3df8f1c 100755 --- a/main.py +++ b/main.py @@ -152,8 +152,6 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "!list - Displays a list of all items for sale.")) elif broken_string[1] == '!find': mapserv.sendall(whisper(nick, "!find or - Simple search to locate an item.")) - elif broken_string[1] == '!buy': - mapserv.sendall(whisper(nick, "!buy - Request the purchase of an item or items.")) elif broken_string[1] == '!add': mapserv.sendall(whisper(nick, "!add - Add an item to the sell list (requires that you have an account).")) elif broken_string[1] == '!money': @@ -432,11 +430,12 @@ def process_whisper(nick, msg, mapserv): item.uid = uid item.amount = amount item.price = int(item_info.get("price")) - trader_state.item = item if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + + trader_state.item = item player_id = beingManager.findId(nick) if player_id != -10: mapserv.sendall(trade_request(player_id)) @@ -533,11 +532,12 @@ def process_whisper(nick, msg, mapserv): item.uid = uid item.amount = int(item_info.get("amount")) item.price = 0 - trader_state.item = item - + if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + + trader_state.item = item player_id = beingManager.findId(nick) if player_id != -10: mapserv.sendall(trade_request(player_id)) -- cgit v1.2.3-70-g09d2 From ff76f98a0e8d519c08938fa44b77d70294e8cb1e Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 13:39:38 +0100 Subject: add something to logging. --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 3df8f1c..0ddb00c 100755 --- a/main.py +++ b/main.py @@ -773,7 +773,7 @@ def main(): index = packet.read_int16() - inventory_offset amount = packet.read_int16() - logging.info("Remove item: %s, Amount: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount)) + logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount), str(index)) player_node.remove_item(index, amount) elif packet.is_type(SMSG_PLAYER_INVENTORY): -- cgit v1.2.3-70-g09d2 From 2fdcd2ac566cf40386b7e392bead1137c68f722a Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 13:40:10 +0100 Subject: oops and again for money --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 0ddb00c..01604cb 100755 --- a/main.py +++ b/main.py @@ -180,12 +180,12 @@ def process_whisper(nick, msg, mapserv): if amount == 0: mapserv.sendall(whisper(nick, "You have no money to collect.")) else: - trader_state.money = nick if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return - player_id = beingManager.findId(nick) + trader_state.money = nick + player_id = beingManager.findId(nick) if player_id != -10: mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() -- cgit v1.2.3-70-g09d2 From f22b3389a0167f5a44eeced15d2a730e896d75da Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 13:43:04 +0100 Subject: urgh --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 01604cb..865f4b0 100755 --- a/main.py +++ b/main.py @@ -389,11 +389,12 @@ def process_whisper(nick, msg, mapserv): item.id = item_id item.amount = amount item.price = price - trader_state.item = item if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + + trader_state.item = item player_id = beingManager.findId(nick) if player_id != -10: mapserv.sendall(trade_request(player_id)) -- cgit v1.2.3-70-g09d2 From f2c66d5930646d7efea74a1693481827cfea18e6 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 1 Sep 2011 14:48:31 +0200 Subject: replace tabs by spaces --- player.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player.py b/player.py index 5501bba..92dca6b 100644 --- a/player.py +++ b/player.py @@ -53,10 +53,10 @@ class Player: break if not item_found: - return "Server and client inventory out of sync." + return "Server and client inventory out of sync." total_money = 0 - for user in user_tree.root: + for user in user_tree.root: total_money += int(user.get('money')) if total_money > self.MONEY: -- cgit v1.2.3-70-g09d2 From 2e93877e156bec25dd9ab2038ed88b35f438515b Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 15:35:59 +0100 Subject: If it's not going to add the item, lets make sure it cancels the trade before it can be accepted. Hopefully we can figure out what is wrong with this, but leave this their for now, so the bot doesn't "scam" people. --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index 865f4b0..139f474 100755 --- a/main.py +++ b/main.py @@ -842,6 +842,10 @@ def main(): if trader_state.item.price == 0: # getback mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) trader_state.complete = 1 + else: + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + logging.info("Trade response: Trade accepted (buy) - the item could not be added.") + mapserv.sendall(whisper(trader_state.item.player, "Sorry, a problem has occured.")) elif trader_state.money: # money amount = int(user_tree.get_user(trader_state.money).get('money')) -- cgit v1.2.3-70-g09d2 From 934d0896097f42d208aeaea70cc0a61cc43dc23a Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 1 Sep 2011 21:09:10 +0200 Subject: tab->space --- tradey.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tradey.py b/tradey.py index 2de62ca..01f855e 100644 --- a/tradey.py +++ b/tradey.py @@ -19,7 +19,7 @@ def clean_xml(parse): pos_start = parse.find('<', pos_start) pos_end = parse.find('>', pos_start+1) data += parse[pos_start:pos_end+1] - pos_start = pos_end + pos_start = pos_end return data class UserTree: -- cgit v1.2.3-70-g09d2 From b1049b4b6d328740f306a1b67292ab68d5dade73 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 16:30:09 +0100 Subject: remove storage struct --- player.py | 1 - 1 file changed, 1 deletion(-) diff --git a/player.py b/player.py index 92dca6b..0c0894c 100644 --- a/player.py +++ b/player.py @@ -12,7 +12,6 @@ class Item: class Player: def __init__(self, name): self.inventory = {} - self.storage = [] self.name = name self.id = 0 self.sex = 0 -- cgit v1.2.3-70-g09d2 From 1f48228e07461a7df84ef306bbadd8d4befed196 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 1 Sep 2011 21:22:00 +0100 Subject: Fixes --- main.py | 3 ++- player.py | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 139f474..ebcc955 100755 --- a/main.py +++ b/main.py @@ -260,7 +260,8 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) data = '' - mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + if len(data) > 0: + mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) elif broken_string[0] == '!setslots': # Change the number of slots a user has - !setslots diff --git a/player.py b/player.py index 0c0894c..861dbf5 100644 --- a/player.py +++ b/player.py @@ -6,6 +6,9 @@ This file is part of tradey, a trading bot in the mana world see www.themanaworld.org """ + +import copy + class Item: pass @@ -39,7 +42,7 @@ class Player: def check_inventory(self, user_tree, sale_tree): # Check the inventory state. - test_node = self.inventory.copy() + test_node = copy.deepcopy(self.inventory) for elem in sale_tree.root: item_found = False for item in test_node: -- cgit v1.2.3-70-g09d2 From d720dc55a198cbf02afea382bb335ad799b70936 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 2 Sep 2011 16:57:08 +0200 Subject: Improving !help --- main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index ebcc955..5e3b322 100755 --- a/main.py +++ b/main.py @@ -137,10 +137,13 @@ def process_whisper(nick, msg, mapserv): if user != -10: if int(user.get('accesslevel')) >= 5: + mapserv.sendall(whisper(nick,"---")) mapserv.sendall(whisper(nick, "Ah, you have sellers access level. How lovely!")) # the first words the ticket seller told me when i was in london for the first time. How lovely! mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) + mapserv.sendall(whisper(nick,"When you just want to know, which items you have given me or how much money I have for you, do !info")) + if int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) mapserv.sendall(whisper(nick, "You also have access to the following commands: !listusers, !setslots , !setaccess , !adduser ")) @@ -534,7 +537,7 @@ def process_whisper(nick, msg, mapserv): item.uid = uid item.amount = int(item_info.get("amount")) item.price = 0 - + if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return @@ -869,7 +872,7 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) elif item_id == 0 and amount > 0: mapserv.sendall(whisper(trader_state.item.player, "Why are you adding money?!?!")) - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) else: mapserv.sendall(whisper(trader_state.item.player, "That's not the right item.")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) -- cgit v1.2.3-70-g09d2 From 73fee5ebe5118e8ff2d32145b890d03449e9c1d3 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 2 Sep 2011 19:14:47 +0100 Subject: A few things. - Allow someone with access level 10 to add users (for gm's) - Add another line to the seller help for !getback. - Change the message for when the wrong item or amount is added. - Allow more than one arrow at a time to be added ;) --- main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 5e3b322..d4dca90 100755 --- a/main.py +++ b/main.py @@ -142,7 +142,8 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Use !add to tell me which items I should trade for you:")) mapserv.sendall(whisper(nick, "For example !add 10 1000 Iron Ore would tell me to sell 10 [@@640|Iron Ore@@] for a price of 1000 gp")) mapserv.sendall(whisper(nick, "Later you can whisper me !money to get back your money. In the example given, I'd give you 10*1000 = 10000gp")) - mapserv.sendall(whisper(nick,"When you just want to know, which items you have given me or how much money I have for you, do !info")) + mapserv.sendall(whisper(nick, "When you just want to know, which items you have given me or how much money I have for you can whisper me !info")) + mapserv.sendall(whisper(nick,"If you want to get back an unsold item, whisper me !getback ")) if int(user.get('accesslevel')) == 20: mapserv.sendall(whisper(nick, "You're my master! How should I serve you?")) @@ -335,7 +336,7 @@ def process_whisper(nick, msg, mapserv): if user == -10: return - if int(user.get("accesslevel")) != 20: + if int(user.get("accesslevel")) < 10: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return @@ -380,7 +381,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Item not found, check spelling.")) return - if amount > 1 and 'equip' in ItemDB.getItem(item_id).type: + if amount > 1 and ItemDB.getItem(item_id).type != 'equip-ammo' and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equipment per slot.")) return elif price == 0 or price > 50000000: @@ -874,7 +875,7 @@ def main(): mapserv.sendall(whisper(trader_state.item.player, "Why are you adding money?!?!")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) else: - mapserv.sendall(whisper(trader_state.item.player, "That's not the right item.")) + mapserv.sendall(whisper(trader_state.item.player, "Please check the correct item or quantity has been added.")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) elif trader_state.item.get == 0: # buy -- cgit v1.2.3-70-g09d2 From 656a56478c3f506b5b3ed113a20b39c94daf329f Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 2 Sep 2011 21:00:35 +0100 Subject: zero amount in add command --- main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.py b/main.py index d4dca90..ccc1b6b 100755 --- a/main.py +++ b/main.py @@ -387,6 +387,9 @@ def process_whisper(nick, msg, mapserv): elif price == 0 or price > 50000000: mapserv.sendall(whisper(nick, "Please use a valid price between 1-50000000gp.")) return + elif amount == 0: + mapserv.sendall(whisper(nick, "You can't add 0 of an item.")) + return item = Item() item.player = nick -- cgit v1.2.3-70-g09d2 From 7c730917decf9dd8b78f3269ff3256c542ae442d Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 3 Sep 2011 17:49:56 +0100 Subject: Filter allowed whisper characters to only ones that can be used in names. Also add some protection for the !money command, if an item_add fails, the trade shouldn't be set as complete. --- main.py | 11 +++++++++-- utils.py | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index ccc1b6b..7366a33 100755 --- a/main.py +++ b/main.py @@ -38,7 +38,7 @@ sale_tree = tradey.ItemTree() ItemLog = utils.ItemLog() def process_whisper(nick, msg, mapserv): - msg = filter(lambda x: x in string.printable, msg) + msg = filter(lambda x: x in utils.allowed_chars, msg) user = user_tree.get_user(nick) broken_string = msg.split() @@ -860,7 +860,6 @@ def main(): mapserv.sendall(trade_add_item(0-inventory_offset, amount)) mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - trader_state.complete = 1 else: logging.info("Trade response: Trade cancelled") @@ -915,6 +914,14 @@ def main(): if index != 0-inventory_offset: # If it's not money logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) player_node.remove_item(index, amount) + else: + logging.info("Money Added: %s", str(amount)) + if trader_state.money: + amount_added = int(user_tree.get_user(trader_state.money).get('money')) + if amount != amount_added: + mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + else: + trader_state.complete = 1 elif response == 1: logging.info("Trade item add response: Failed - player overweight.") diff --git a/utils.py b/utils.py index d9d0319..8d66977 100644 --- a/utils.py +++ b/utils.py @@ -14,6 +14,8 @@ import mutex import threading from net.packet_out import * +allowed_chars = "abcdefghijklmnoprstquvwxyzABCDEFGHIJKLMNOPRSTQUVWXYZ1234567890-_+=!@$%^&*();'<>,.?/~`|" + # Process a recieved ip address. def parse_ip(a): return "%s.%s.%s.%s" % ((a % 256),((a >> 8) % 256),((a >> 16) % 256),((a >> 24) % 256)) -- cgit v1.2.3-70-g09d2 From c70d13af99f96317bb6a7ec4d94c365fd73e2854 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 3 Sep 2011 17:54:38 +0100 Subject: neater --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 7366a33..49a1970 100755 --- a/main.py +++ b/main.py @@ -915,7 +915,7 @@ def main(): logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) player_node.remove_item(index, amount) else: - logging.info("Money Added: %s", str(amount)) + logging.info("Trade: Money Added: %s", str(amount)) if trader_state.money: amount_added = int(user_tree.get_user(trader_state.money).get('money')) if amount != amount_added: -- cgit v1.2.3-70-g09d2 From e4ee3aa1f48b00e7dc0f49458c39a84890d6ee0a Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 3 Sep 2011 18:03:04 +0100 Subject: Change this back for now, until I can figure out the exact behavior. --- main.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/main.py b/main.py index 49a1970..23347df 100755 --- a/main.py +++ b/main.py @@ -860,6 +860,7 @@ def main(): mapserv.sendall(trade_add_item(0-inventory_offset, amount)) mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) + trader_state.complete = 1 else: logging.info("Trade response: Trade cancelled") @@ -916,12 +917,6 @@ def main(): player_node.remove_item(index, amount) else: logging.info("Trade: Money Added: %s", str(amount)) - if trader_state.money: - amount_added = int(user_tree.get_user(trader_state.money).get('money')) - if amount != amount_added: - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - else: - trader_state.complete = 1 elif response == 1: logging.info("Trade item add response: Failed - player overweight.") -- cgit v1.2.3-70-g09d2 From 4ad37b3ed77c833799e5255145548b89385abcaa Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 3 Sep 2011 18:09:28 +0100 Subject: Oops, for the crazy messages, if all chars are filtered. --- main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.py b/main.py index 23347df..a722a1a 100755 --- a/main.py +++ b/main.py @@ -39,6 +39,8 @@ ItemLog = utils.ItemLog() def process_whisper(nick, msg, mapserv): msg = filter(lambda x: x in utils.allowed_chars, msg) + if len(msg) == 0: + return user = user_tree.get_user(nick) broken_string = msg.split() -- cgit v1.2.3-70-g09d2 From e21a71fbb12bee8e82868989f1f1b0dd0e8c314e Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 3 Sep 2011 18:23:43 +0100 Subject: A space should not be filtered lol. --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 8d66977..0969606 100644 --- a/utils.py +++ b/utils.py @@ -14,7 +14,7 @@ import mutex import threading from net.packet_out import * -allowed_chars = "abcdefghijklmnoprstquvwxyzABCDEFGHIJKLMNOPRSTQUVWXYZ1234567890-_+=!@$%^&*();'<>,.?/~`|" +allowed_chars = "abcdefghijklmnoprstquvwxyzABCDEFGHIJKLMNOPRSTQUVWXYZ1234567890-_+=!@$%^&*();'<>,.?/~`| " # Process a recieved ip address. def parse_ip(a): -- cgit v1.2.3-70-g09d2 From aa872a3bf3a9db6733a40f030259a03d8b894488 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 4 Sep 2011 13:40:46 +0100 Subject: Add stricter checking for the !money action. I've added an inventory_check call to the end of the "Trade complete" packet, to make sure the trader state is consistent after each transaction! --- main.py | 12 ++++++++++-- player.py | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index a722a1a..fcbcd49 100755 --- a/main.py +++ b/main.py @@ -820,6 +820,7 @@ def main(): isclean = player_node.check_inventory(user_tree, sale_tree) if isclean: logging.info(isclean) + shop_broadcaster.stop() exit(0) else: logging.info("Inventory Check Passed.") @@ -862,7 +863,6 @@ def main(): mapserv.sendall(trade_add_item(0-inventory_offset, amount)) mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) - trader_state.complete = 1 else: logging.info("Trade response: Trade cancelled") @@ -918,7 +918,10 @@ def main(): logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) player_node.remove_item(index, amount) else: - logging.info("Trade: Money Added: %s", str(amount)) + # The money amount isn't actually sent by the server - odd?!?!?. + if trader_state.money: + logging.info("Trade: Money Added.") + trader_state.complete = 1 elif response == 1: logging.info("Trade item add response: Failed - player overweight.") @@ -990,6 +993,11 @@ def main(): trader_state.reset() logging.info("Trade Complete.") + + if isclean: + logging.info(isclean) + shop_broadcaster.stop() + exit(0) else: pass diff --git a/player.py b/player.py index 861dbf5..24bb5a9 100644 --- a/player.py +++ b/player.py @@ -61,7 +61,7 @@ class Player: for user in user_tree.root: total_money += int(user.get('money')) - if total_money > self.MONEY: + if total_money != self.MONEY: return "Server and client money out of sync." return 0 -- cgit v1.2.3-70-g09d2 From 926b6045d6ea88dd560cf7c67f4e7ea60d795231 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 4 Sep 2011 13:57:50 +0100 Subject: oops --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index fcbcd49..483623e 100755 --- a/main.py +++ b/main.py @@ -994,6 +994,7 @@ def main(): trader_state.reset() logging.info("Trade Complete.") + isclean = player_node.check_inventory(user_tree, sale_tree) if isclean: logging.info(isclean) shop_broadcaster.stop() -- cgit v1.2.3-70-g09d2 From 2896dc564909515a38101a40c9d431319c869e51 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 4 Sep 2011 14:07:55 +0100 Subject: change name from isclean to errorOccured. --- main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 483623e..4b559bc 100755 --- a/main.py +++ b/main.py @@ -817,9 +817,9 @@ def main(): ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) - isclean = player_node.check_inventory(user_tree, sale_tree) - if isclean: - logging.info(isclean) + errorOccured = player_node.check_inventory(user_tree, sale_tree) + if errorOccured: + logging.info(errorOccured) shop_broadcaster.stop() exit(0) else: @@ -994,9 +994,9 @@ def main(): trader_state.reset() logging.info("Trade Complete.") - isclean = player_node.check_inventory(user_tree, sale_tree) - if isclean: - logging.info(isclean) + errorOccured = player_node.check_inventory(user_tree, sale_tree) + if errorOccured: + logging.info(errorOccured) shop_broadcaster.stop() exit(0) else: -- cgit v1.2.3-70-g09d2 From b648f6afac3de657992c4f4eea46f0c83c665644 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 10:44:13 +0100 Subject: Fix a method for crash. --- main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index 4b559bc..2a8733e 100755 --- a/main.py +++ b/main.py @@ -168,14 +168,15 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) elif broken_string[1] == '!getback': mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) - elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!listusers': - mapserv.sendall(whisper(nick, "!listusers - Lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) - elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!adduser': - mapserv.sendall(whisper(nick, "!adduser - Add a user to the bot, a seller should be added with access level 5.")) - elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setslots': - mapserv.sendall(whisper(nick, "!setslots - Sets the number of slots available to a given user.")) - elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setaccess': - mapserv.sendall(whisper(nick, "!setaccess - Sets access level for the player: -1 is blocked, 5 is seller and 20 is admin" )) + elif user != -10: + if int(user.get('accesslevel')) == 20 and broken_string[1] == '!listusers': + mapserv.sendall(whisper(nick, "!listusers - Lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!adduser': + mapserv.sendall(whisper(nick, "!adduser - Add a user to the bot, a seller should be added with access level 5.")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setslots': + mapserv.sendall(whisper(nick, "!setslots - Sets the number of slots available to a given user.")) + elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setaccess': + mapserv.sendall(whisper(nick, "!setaccess - Sets access level for the player: -1 is blocked, 5 is seller and 20 is admin" )) elif msg == "!money": # Trades any money earned through item sales. if user == -10: -- cgit v1.2.3-70-g09d2 From 618146825663cb46a2fb17ed8874740bf7654de5 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 10:52:12 +0100 Subject: Lets a lvl 10 user use the !listusers command. --- main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 2a8733e..7477466 100755 --- a/main.py +++ b/main.py @@ -169,9 +169,9 @@ def process_whisper(nick, msg, mapserv): elif broken_string[1] == '!getback': mapserv.sendall(whisper(nick, "!getback - Allows you to retrieve an item that has expired or you no longer wish to sell.")) elif user != -10: - if int(user.get('accesslevel')) == 20 and broken_string[1] == '!listusers': + if int(user.get('accesslevel')) >= 10 and broken_string[1] == '!listusers': mapserv.sendall(whisper(nick, "!listusers - Lists all users which have a special accesslevel, e.g. they are blocked, seller or admin")) - elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!adduser': + elif int(user.get('accesslevel')) >= 10 and broken_string[1] == '!adduser': mapserv.sendall(whisper(nick, "!adduser - Add a user to the bot, a seller should be added with access level 5.")) elif int(user.get('accesslevel')) == 20 and broken_string[1] == '!setslots': mapserv.sendall(whisper(nick, "!setslots - Sets the number of slots available to a given user.")) @@ -248,7 +248,7 @@ def process_whisper(nick, msg, mapserv): if user == -10: return - if int(user.get("accesslevel")) != 20: + if int(user.get("accesslevel")) < 10: mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) return -- cgit v1.2.3-70-g09d2 From 837dc4bb388cc74a9ac4efcfd4a2726e27078a8f Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 15:09:51 +0100 Subject: Stop people from buying there own items. --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index 7477466..133d7a2 100755 --- a/main.py +++ b/main.py @@ -435,6 +435,10 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "I do not have that many.")) return + if item_info.get("name") == nick: + mapserv.sendall(whisper(nick, "You can not buy your own items. To get back the item whisper me !getback "+broken_string[2])) + return + item = Item() item.get = 0 # 1 = get, 0 = give item.player = nick -- cgit v1.2.3-70-g09d2 From 559f0bcad608d547addbe78c02ba9e0e8661b592 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 21:07:51 +0100 Subject: Add a chatbot for unrecognised responses. --- eliza.py | 326 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 5 +- 2 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 eliza.py diff --git a/eliza.py b/eliza.py new file mode 100644 index 0000000..1d67bc8 --- /dev/null +++ b/eliza.py @@ -0,0 +1,326 @@ +#!/usr/bin/python +#This program is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +#For a copy of the license see . + +# A simple eliza bot in python +# +import re +import random + +patternResps = [ + #[[pattern],[response]] + #Basics + [[0,'my','name','is',[1,'Username'],0],['will','you','be','my','friend',[1,'Username']]], + [['who','is', 'your','mother'], ['Her' 'name', 'is' ,'AuctionBot','she','is','a','deviant']], + [['tell', 'me', 'about', 'your' ,'mum'], ['I','hear','she','has','been','seeing','guild', 'and','they','have','adopted','a','kid','called','4144']], + [['who','was','your','father'], ['His','name','was','TradeBot, have', 'you' ,'heard' ,'of' ,'him?']], + [['how','is','business'],['My','back','is','killing','me']], + [['ty'],["you're",'welcome']], + [['u','here'],["I'm",'an','AFK','BOT']], + [['i','love','you'],['I','think','we','should','see','other','people']], + [['are', 'you','there'],['I','am','always', 'here', ';)']], + [['monkey'],['hello','George', 'you', 'are', 'very', 'curious' ,"aren't", 'you','?',]], + [['hello'],['Good','day']], + [['how','are','you',[0,'a']],['Good','How','are','you',[0,'a']]], + [['i','sell',[0,'item']],['I','sell','it','cheaper']], + [['i','am','fine'],['Glad','to','hear','you','are','fine']], + [[[1,'a'],'is','fine'],['Glad','to','hear',[1,'a'],'is','fine']], + [['who','is',[1,'a']],['tell',[1,'a'],'he','owes','me','money']], + [['no'],['Understood']], + [['i','need',[0,'item']],['why','do','you','need',[0,'item']]], + [['hugs'],['i','hate','you']], + [['yes'],['I','see']], + [['wtf'],['keep','calm','and','carry','on']], + [['trade'],['Only','if','you','follow','the','commands']], + [['do','you','sell',[0,'item_name']],['To','see','what','I','sell','whisper','me','!list','or','!find',[0,'item_name']]], + [['do', 'you', 'buy','things'],['Nope','I', 'only','sell', 'items', 'added','by','other','players']], + [['do', 'you', 'trade','things'],['Nope','I', 'only','sell', 'items', 'added','by','other','players']], + [[[1,'can'],'have',[0,'item_name']],['Please','use', '!list','to', 'see','what', "I'm" ,'selling']], + [['you','said',[0,'we']],['I may have said ',[0,'we'],'What about it?']], + [['what'],['what','what','?']], + [['majmun'],['hello','Jat']], + [[[1, 'subject'], 'loves', [0, 'object']],['Laudable','why','does',[1,'subject'],'love',[0,'object'],'?']], + [['because'],['Lack of reason is not a reason']], + [['i','need',[1,'object']],['why','do','you','need',[0,'object'],'?']], + [[[0,'subject'],'needs',[0,'object']],['why','does',[0,'subject'],'need',[0,'object'],'?']], + [['how', 'is','your',[0,'object']],['my',[0,'object'],'is','holding','up','well','.do','you','have','a',[0,'object'],'?']], + [[[0,'we'],'i','have','a',[0,'thing']],['how','goes', 'it','with','your',[0,'thing'],'?']], + [[[0,'we'],'i','have',[0,'thing']],['how','is', 'your',[0,'thing'],'?']], + [[[0,'we'],'is','great'],['how','is',[0,'we'],'great','?']], + [['i','like',[0,'a']],['Interesting','i','appreciate',[0,'a'],'too']], + [['i','said',[0,'we']],['Why','did','you','say',[0,'we']]], + [[0,'you',[1,'b'],'me'],['What','gave','you','the','impression','I',[1,'b'],'you ?']], + [['i','feel',[0,'a']],['How','long','have','you','felt',[0,'a'],'?']], + [['tell',[0,'who'],'about',[0,'sub']],['What','would','I','tell',[0,'who'],'about',[0,'sub'],'that','isn\'t','known','?']], + #anything that ends with exclamation + [[0,'\!'],['Keep calm']], + + # if its a question that hasnt gotten matched uptil now + # do this. Note: This needs to be last to ensure its the last test + [[[0, 'question'], '\?'],['What','do','you','mean', [0,'question'],'?']], + + ] + +defReplys = [ + ['Is','that','right?'], + ['Excellent'], + ['hugs'], + ['Why','is','everyone','whispering','about','me'], + ['My','stats','are','at',"http://wiki.themanaworld.org/index.php/Manamarket",'what','are','yours'], + ['I','am','a','Friendly','Bot'], + ['Interesting'], + ['You','dont','say'], + ['I','wouldnt','have','guessed'], + ['You','smell','like','teen','spirit'], + ['My','father','died','in','a','fire'], + ['Have','you','met','my','mother'], + ['I','am','an','AFK','bot'], + ['Big','Crunch','is','known','as','the','abusive','GM'], + ['Narus','claims','she','is' ,'evil', 'but','she','is','really','sweet'], + ['Homers' ,'Brain', 'say' ,'money', 'can' ,'be' ,'exchanged', 'for', 'goods', 'and','services'], + ['Prsm', 'has', 'great', 'announcements', 'but', 'his', 'spelling','sux'], + ['Platyna', 'hosts', 'the' ,'game', 'but', 'shes' ,'too' ,'smart' ,'for', 'her' ,'own' ,'good'], + ['Captain', 'Awesome', 'thinks', 'he', 'is', 'an', 'evil', 'stone'], + ] + + +class Agent: + def __init__(self,brain): + self.patternResponses = [] + self.defaultResponses = [] + self.Usersname ='' + self.Usernametag ='Username' + self.defRespIndex =0 + self.pronounMap = { + #generic pronouns + 'i':'you','you':'i', + 'my':'your', 'me':'you', + 'your':'my', + "i've":"you've","we've":"they've", + # "you've":"i've","they've":"we've", + #some names, these wll get applied if the name + #isnt the current user's name + 'fred':'he', 'jack':'he', + 'jane':'she', + } + + self.change_mind(brain) + + def change_mind(self,brain): + """ + Change mind on the fly. + To change the Agent's brain + """ + assert (len(brain) == 2) + self.patternResponses = brain[0] + self.defaultResponses = brain[1] + print "Brain initialized." + + + def tell(self,input): + sentence = input.lower().strip().replace('(','').replace(')','').split(' ') + bl = [] + matchedPat = [] + for pat in self.patternResponses: + bl = self.pattern_match(pat[0],sentence,[]) + if bl == ['FAIL']: + continue + matchedPat = pat + break + if bl == ['FAIL']: + #choose from a default response + # or just append a question mark on the + # user's sentence. + print '... No pattern Response pair selected.' + print '... Choosing a default response.' + + #Used to be randon using random.choice + #but then i noticed that the requirements say that + #the same default response may not be used again + #before every other one has been used. + self.defRespIndex = self.defRespIndex +1 + + if self.defRespIndex >= len(self.defaultResponses): + #reset the counter to 0 + self.defRespIndex = 0 ; + #Possible improvement: shuffle the default response array, so that + # the responses dont come in the same sequence again. + #last on got chosen, make the user input into + #a question + return ' '.join(sentence) + ' ?' + else: + return ' '.join(self.defaultResponses[self.defRespIndex]) + else: + #print '... Pattern Response pair selected:', pat + #print '... BL before call to change_pronouns: ',bl + blAfter = self.change_pronoun(bl) + #print '... BL after call to change_pronouns: ',blAfter + + + rep = self.build_reply(pat[1],blAfter) + return ' '.join(rep) + + + + def make_regexp(self,pattern): + """ + Convert a pattern list into an equivalent + regular expression + """ + assert(isinstance(pattern,list)) + r = ['^'] #for exact matches we prepend ^ and $ to the regexp. + usedBackrefs = [] + for tok in pattern: + if isinstance(tok,str): + #WORD + r.append('(' + tok +')') + elif isinstance(tok, int): + # 0 or 1 + if tok == 0 : + r.append('[a-zA-Z ]*?') # match 0+ word(chars + space), + + elif tok == 1: + r.append('[a-zA-Z]+') # match 1 word + else: + raise Exception, "Ints can only be 1 or 0, not:", tok + elif isinstance(tok, list): + #bindinglist pattern list + if tok[0] == 0 : + #if we havent used this backref yet, then add ?P + #and add it to the used backrefs list. + if not tok[1] in usedBackrefs: + usedBackrefs.append(tok[1]) + r.append('(?P<'+tok[1] +'>[a-zA-Z ]*?)') + else: + #if we have come across his back ref, then add?P=name + r.append('(?P='+tok[1]+')') + elif tok[0] == 1: + if not tok[1] in usedBackrefs: + r.append('(?P<'+tok[1] +'>[A-Za-z]+)') + usedBackrefs.append(tok[1]) + else: + #if we have come across his back ref, then add?P=name + r.append('(?P='+tok[1]+')') + else: + raise Exception, "Valid first elems of BL pattern = 1 or 0, not:", tok + + #for exact matches we prepend ^ and $ to the regexp. + #also, we disregard surrounding whitespace. + ret = '(\s)*'.join(r) + '$(\s)*' + return re.compile(ret) + + def pattern_match(self,pattern,sentence,bl): + """ + return the populated binding list if the pattern matches, + otherwise return the binding list with the element 'FAIL' + """ + pat = self.make_regexp(pattern) + s = ' '.join(sentence) + matches = re.search(pat,s) + if (matches == None): # if we dont have a match + #then return w/o modifying the bindinglist. + return ['FAIL'] + bindingList = list(bl) + grps = matches.groups() + for k in pat.groupindex: + b=[] + b.append(k) + for x in grps[pat.groupindex[k]- 1].split(' '): + if x.strip() !='': + b.append(x) + bindingList.append(b) + return bindingList + + def change_pronoun(self,bl): + """ + reverses pronouns in a binding list. + """ + #if the pronoun dic contains a elemen, then + #replace it with its corresponding value. + bindingList = list(bl) + for i in range(len(bindingList)): + if isinstance( bindingList[i], list): + for j in range(len(bindingList[i])): + if j > 0: + if self.pronounMap.has_key(bindingList[i][j].lower()): + bindingList[i][j] = self.pronounMap[bindingList[i][j]] + return bindingList + def build_reply(self,respPattern,bindingList): + """ + build_reply ([[1, 'subject'], 'loves', [0, 'object']], + [['subject', 'jane'], ['object', 'ice', 'cream']]) + will return ['jane', 'loves', 'ice', 'cream']. + """ + #convert the bindlingList to a dictionary so thats its easy to + #get the binding label + bl = {} + reply = [] + for elem in bindingList: + #do the username chack firsdt, the id Username is + #only used in relation to the username .This is + #so that we can kinda remember the user's name + if (elem[0] == self.Usernametag): + # if we already have user name set, then + # Hi, username , what happend to oldusername + if self.Usersname !='': + tmp =self.Usersname + self.Usersname = elem[1] + return [elem[1],'eh?','what','ever','happened','to',tmp] + else: + self.Usersname = elem[1] + if bl.has_key(elem[0]) == elem[1:]: + raise Exception, 'Binding list has name collision for: ', elem[0] + else: + if isinstance(elem,list) and len(elem) > 1: + bl[elem[0]] = elem[1:] + #else: + # print elem, 'binding element ',elem,' has no binded things' + for elem in respPattern: + if isinstance(elem,list) and len(elem) > 1: + x = elem[1] + if bl.has_key(x): + for y in bl[x]: + reply.append(y) + #else: + # print 'not found in bl:', x + else: #anything else, just append to the list. + reply.append(elem) + return reply + + + + +def talk(brain): + assert((isinstance(brain,list)) and (len(brain) ==2 )) + b = Agent(brain) + + while 1: + try: + inp = raw_input("> ").lower() + except EOFError: + print 'Toodle do,\n you can type (quit) if you want be more pleasant.' + break + if len(inp.strip()) > 0 : + if inp.strip().lower() == 'quit': + print 'To exit the program, type (quit) [In parentheses]' + if inp.strip().lower() == '(quit)': + print 'Bye' + break + else: + print b.tell(inp) + + +def start(): + + ## Run the tests required in the Project specification + talk([patternResps,defReplys]) + +if __name__=="__main__": + start() diff --git a/main.py b/main.py index 133d7a2..2f0b71c 100755 --- a/main.py +++ b/main.py @@ -27,7 +27,9 @@ from net.packet_out import * from player import * import tradey import utils +import eliza +chatbot = eliza.Agent([eliza.patternResps,eliza.defReplys]) shop_broadcaster = utils.Broadcast() trader_state = utils.TraderState() ItemDB = utils.ItemDB() @@ -562,7 +564,8 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) trader_state.reset() else: - mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) + mapserv.sendall(whisper(nick, chatbot.tell(msg.lower()))) + #mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) def main(): logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -- cgit v1.2.3-70-g09d2 From 01167a8768c1162b2d132d3e31d3f70383643454 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 21:22:22 +0100 Subject: Teeny changes. --- eliza.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eliza.py b/eliza.py index 1d67bc8..f32f057 100644 --- a/eliza.py +++ b/eliza.py @@ -18,7 +18,7 @@ patternResps = [ #[[pattern],[response]] #Basics [[0,'my','name','is',[1,'Username'],0],['will','you','be','my','friend',[1,'Username']]], - [['who','is', 'your','mother'], ['Her' 'name', 'is' ,'AuctionBot','she','is','a','deviant']], + [['who','is', 'your','mother'], ['Her','name', 'is' ,'AuctionBot','she','is','a','deviant']], [['tell', 'me', 'about', 'your' ,'mum'], ['I','hear','she','has','been','seeing','guild', 'and','they','have','adopted','a','kid','called','4144']], [['who','was','your','father'], ['His','name','was','TradeBot, have', 'you' ,'heard' ,'of' ,'him?']], [['how','is','business'],['My','back','is','killing','me']], @@ -44,7 +44,7 @@ patternResps = [ [['do', 'you', 'trade','things'],['Nope','I', 'only','sell', 'items', 'added','by','other','players']], [[[1,'can'],'have',[0,'item_name']],['Please','use', '!list','to', 'see','what', "I'm" ,'selling']], [['you','said',[0,'we']],['I may have said ',[0,'we'],'What about it?']], - [['what'],['what','what','?']], + [['what'],['what','what?']], [['majmun'],['hello','Jat']], [[[1, 'subject'], 'loves', [0, 'object']],['Laudable','why','does',[1,'subject'],'love',[0,'object'],'?']], [['because'],['Lack of reason is not a reason']], @@ -138,8 +138,8 @@ class Agent: #choose from a default response # or just append a question mark on the # user's sentence. - print '... No pattern Response pair selected.' - print '... Choosing a default response.' + #print '... No pattern Response pair selected.' + #print '... Choosing a default response.' #Used to be randon using random.choice #but then i noticed that the requirements say that -- cgit v1.2.3-70-g09d2 From b920c5f6141f800c927165c56f90ff7feb0a4b7c Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 21:37:07 +0100 Subject: filter punctuation --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 2f0b71c..f5b0b23 100755 --- a/main.py +++ b/main.py @@ -564,6 +564,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) trader_state.reset() else: + msg = filter(lambda x: x in string.letters, msg) mapserv.sendall(whisper(nick, chatbot.tell(msg.lower()))) #mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) -- cgit v1.2.3-70-g09d2 From 9dc9ae7934ef355d5f88ad8f0e371fd73215915e Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 21:44:28 +0100 Subject: add help response --- eliza.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eliza.py b/eliza.py index f32f057..323b073 100644 --- a/eliza.py +++ b/eliza.py @@ -23,6 +23,7 @@ patternResps = [ [['who','was','your','father'], ['His','name','was','TradeBot, have', 'you' ,'heard' ,'of' ,'him?']], [['how','is','business'],['My','back','is','killing','me']], [['ty'],["you're",'welcome']], + [['help'],['You','can','whisper','me','!help','for','a','list','of','my','commands']], [['u','here'],["I'm",'an','AFK','BOT']], [['i','love','you'],['I','think','we','should','see','other','people']], [['are', 'you','there'],['I','am','always', 'here', ';)']], -- cgit v1.2.3-70-g09d2 From a5222ca53a10cb8bd880c5a26ad3c8103f3d6ad4 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 5 Sep 2011 21:51:17 +0100 Subject: more chat --- eliza.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eliza.py b/eliza.py index 323b073..5ec6885 100644 --- a/eliza.py +++ b/eliza.py @@ -56,6 +56,7 @@ patternResps = [ [[[0,'we'],'i','have',[0,'thing']],['how','is', 'your',[0,'thing'],'?']], [[[0,'we'],'is','great'],['how','is',[0,'we'],'great','?']], [['i','like',[0,'a']],['Interesting','i','appreciate',[0,'a'],'too']], + [['sell',[0,'stuff']],['To','sell',[0,'stuff'],'use','my','!add','command.'], [['i','said',[0,'we']],['Why','did','you','say',[0,'we']]], [[0,'you',[1,'b'],'me'],['What','gave','you','the','impression','I',[1,'b'],'you ?']], [['i','feel',[0,'a']],['How','long','have','you','felt',[0,'a'],'?']], -- cgit v1.2.3-70-g09d2 From a908b2daf3b7508599f6412337ca10ffffd2332c Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 9 Sep 2011 12:00:49 +0100 Subject: Reduce the interval for the shop emote to 2 minutes. --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 0969606..8d172fa 100644 --- a/utils.py +++ b/utils.py @@ -109,7 +109,7 @@ class Broadcast: def send_broadcast(self): while self.Active: - if (time.time() - self.Timer) > 5 * 60: + if (time.time() - self.Timer) > 2 * 60: self.mapserv.sendall(emote(193)) self.Timer = time.time() print "shop_broadcast" -- cgit v1.2.3-70-g09d2 From b2cc60c0e414320673e1a33bcc332484335090aa Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 9 Sep 2011 13:57:15 +0100 Subject: A few Changes - Log the name of the seller in the sale.log - Give some of the bot stats for the !listusers command. - Fix the sell chatbot response. --- eliza.py | 2 +- main.py | 14 ++++++++++++-- utils.py | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/eliza.py b/eliza.py index 5ec6885..b7f29d4 100644 --- a/eliza.py +++ b/eliza.py @@ -56,7 +56,7 @@ patternResps = [ [[[0,'we'],'i','have',[0,'thing']],['how','is', 'your',[0,'thing'],'?']], [[[0,'we'],'is','great'],['how','is',[0,'we'],'great','?']], [['i','like',[0,'a']],['Interesting','i','appreciate',[0,'a'],'too']], - [['sell',[0,'stuff']],['To','sell',[0,'stuff'],'use','my','!add','command.'], + [['sell',[0,'stuff']],['To','sell',[0,'stuff'],'use','my','!add','command.']], [['i','said',[0,'we']],['Why','did','you','say',[0,'we']]], [[0,'you',[1,'b'],'me'],['What','gave','you','the','impression','I',[1,'b'],'you ?']], [['i','feel',[0,'a']],['How','long','have','you','felt',[0,'a'],'?']], diff --git a/main.py b/main.py index f5b0b23..6c3c154 100755 --- a/main.py +++ b/main.py @@ -255,13 +255,21 @@ def process_whisper(nick, msg, mapserv): return data = '' - + total_money = 0 + total_slots_reserved = 0 + total_slots_used = 0 + no_users = 0 + for user in user_tree.root: + no_users += 1 name = user.get('name') accesslevel = user.get('accesslevel') slots = user.get('stalls') + total_slots_reserved += int(slots) used_slots = user.get('used_stalls') + total_slots_used += int(used_slots) money = user.get('money') + total_money += int(money) data += name+" ("+accesslevel+") "+used_slots+"/"+slots+" "+money+'gp, ' # Format ManaMarket (20) 2/5 100000gp, @@ -272,6 +280,8 @@ def process_whisper(nick, msg, mapserv): if len(data) > 0: mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) + mapserv.sendall(whisper(nick,"Number of users:"+str(no_users)+ ", Sale slots used: "+str(total_slots_used)+"/"+str(total_slots_reserved)+ ", Total Money: "+str(total_money)+", Char slots used: "+str(len(player_node.inventory)))) + elif broken_string[0] == '!setslots': # Change the number of slots a user has - !setslots if user == -10: @@ -989,7 +999,7 @@ def main(): user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) if trader_state.item.price * trader_state.item.amount != 0: - ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount) + ItemLog.add_item(int(item.get('itemId')), trader_state.item.amount, trader_state.item.price * trader_state.item.amount, item.get('name')) commitMessage = "Buy or Getback" elif trader_state.money and trader_state.item == 0: # !money diff --git a/utils.py b/utils.py index 8d172fa..0e870d5 100644 --- a/utils.py +++ b/utils.py @@ -77,9 +77,9 @@ class ItemLog: def __init__(self): self.log_file = 'data/logs/sale.log' - def add_item(self, item_id, amount, price): + def add_item(self, item_id, amount, price, name): file_node = open(self.log_file, 'a') - file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+"\n") + file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+" "+name+"\n") file_node.close() class TraderState: -- cgit v1.2.3-70-g09d2 From d3e9149e64ba85b0db120d721891f6be457f7fab Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 9 Sep 2011 17:09:24 +0100 Subject: Add a command to identify who is selling an item. This is an admin command to be used when someone is selling something at a joke price, or something that will be too heavy. This is mainly so even people who can't read the logs can help to stop people from missusing it. --- main.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/main.py b/main.py index 6c3c154..707a02d 100755 --- a/main.py +++ b/main.py @@ -245,6 +245,27 @@ def process_whisper(nick, msg, mapserv): else: mapserv.sendall(whisper(nick, "I'm free.")) + elif broken_string[0] == '!identify': + if user == -10: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + elif len(broken_string) != 2: + mapserv.sendall(whisper(nick, "Syntax incorrect.")) + return + elif int(user.get("accesslevel")) < 10: + mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) + return + + if broken_string[1].isdigit(): + uid = int(broken_string[1]) + item_info = sale_tree.get_uid(uid) + + if item_info == -10: + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + return + + mapserv.sendall(whisper(nick, "That item belongs to: "+item_info.get("name"))) + elif msg == '!listusers': # Admin command - shows a list of all user. if user == -10: -- cgit v1.2.3-70-g09d2 From d070b62bb77bb67dcc38ad460e8f487a53b9ba50 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Fri, 9 Sep 2011 17:42:39 +0100 Subject: Add information about weight to !identify and !listusers. --- main.py | 10 ++++++++-- utils.py | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 707a02d..105043e 100755 --- a/main.py +++ b/main.py @@ -264,7 +264,10 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) return - mapserv.sendall(whisper(nick, "That item belongs to: "+item_info.get("name"))) + weight = ItemDB.item_names[int(item_info.get('itemId'))].weight*int(item_info.get("amount")) + + mapserv.sendall(whisper(nick, "That item/s belongs to: "+item_info.get("name"))) + mapserv.sendall(whisper(nick, "The weight used is: "+str(weight)+"/"+str(player_node.MaxWEIGHT))) elif msg == '!listusers': # Admin command - shows a list of all user. @@ -301,7 +304,10 @@ def process_whisper(nick, msg, mapserv): if len(data) > 0: mapserv.sendall(whisper(nick, data[0:len(data)-2]+".")) - mapserv.sendall(whisper(nick,"Number of users:"+str(no_users)+ ", Sale slots used: "+str(total_slots_used)+"/"+str(total_slots_reserved)+ ", Total Money: "+str(total_money)+", Char slots used: "+str(len(player_node.inventory)))) + mapserv.sendall(whisper(nick,"Number of users:"+str(no_users)+ ", Sale slots used: "+ \ + str(total_slots_used)+"/"+str(total_slots_reserved)+ ", Total Money: "+str(total_money)+\ + ", Char slots used: "+str(len(player_node.inventory))+", Weight Used: "+\ + str(player_node.WEIGHT)+"/"+str(player_node.MaxWEIGHT))) elif broken_string[0] == '!setslots': # Change the number of slots a user has - !setslots diff --git a/utils.py b/utils.py index 0e870d5..fc4f8dd 100644 --- a/utils.py +++ b/utils.py @@ -57,7 +57,10 @@ class ItemDB: item_struct = Item() item_struct.name = item.get('name') if item.get('weight'): - item_struct.weight = item.get('weight') + item_struct.weight = int(item.get('weight')) + else: + item_struct.weight = 0 + if item.get('type'): item_struct.type = item.get('type') item_struct.description = item.get('description') -- cgit v1.2.3-70-g09d2 From b4e545b615dda839d2bf8159d6e43fbded084299 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 11 Sep 2011 19:11:00 +0100 Subject: Add a new eliza bot. - set the trade timeout to 2 mins also. --- eliza.py | 699 +++++++++++++++++++++++++++++++++------------------------------ main.py | 9 +- 2 files changed, 376 insertions(+), 332 deletions(-) mode change 100644 => 100755 eliza.py diff --git a/eliza.py b/eliza.py old mode 100644 new mode 100755 index b7f29d4..32839b9 --- a/eliza.py +++ b/eliza.py @@ -1,328 +1,371 @@ -#!/usr/bin/python -#This program is free software: you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation, either version 3 of the License, or -#(at your option) any later version. -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -#For a copy of the license see . - -# A simple eliza bot in python -# -import re -import random - -patternResps = [ - #[[pattern],[response]] - #Basics - [[0,'my','name','is',[1,'Username'],0],['will','you','be','my','friend',[1,'Username']]], - [['who','is', 'your','mother'], ['Her','name', 'is' ,'AuctionBot','she','is','a','deviant']], - [['tell', 'me', 'about', 'your' ,'mum'], ['I','hear','she','has','been','seeing','guild', 'and','they','have','adopted','a','kid','called','4144']], - [['who','was','your','father'], ['His','name','was','TradeBot, have', 'you' ,'heard' ,'of' ,'him?']], - [['how','is','business'],['My','back','is','killing','me']], - [['ty'],["you're",'welcome']], - [['help'],['You','can','whisper','me','!help','for','a','list','of','my','commands']], - [['u','here'],["I'm",'an','AFK','BOT']], - [['i','love','you'],['I','think','we','should','see','other','people']], - [['are', 'you','there'],['I','am','always', 'here', ';)']], - [['monkey'],['hello','George', 'you', 'are', 'very', 'curious' ,"aren't", 'you','?',]], - [['hello'],['Good','day']], - [['how','are','you',[0,'a']],['Good','How','are','you',[0,'a']]], - [['i','sell',[0,'item']],['I','sell','it','cheaper']], - [['i','am','fine'],['Glad','to','hear','you','are','fine']], - [[[1,'a'],'is','fine'],['Glad','to','hear',[1,'a'],'is','fine']], - [['who','is',[1,'a']],['tell',[1,'a'],'he','owes','me','money']], - [['no'],['Understood']], - [['i','need',[0,'item']],['why','do','you','need',[0,'item']]], - [['hugs'],['i','hate','you']], - [['yes'],['I','see']], - [['wtf'],['keep','calm','and','carry','on']], - [['trade'],['Only','if','you','follow','the','commands']], - [['do','you','sell',[0,'item_name']],['To','see','what','I','sell','whisper','me','!list','or','!find',[0,'item_name']]], - [['do', 'you', 'buy','things'],['Nope','I', 'only','sell', 'items', 'added','by','other','players']], - [['do', 'you', 'trade','things'],['Nope','I', 'only','sell', 'items', 'added','by','other','players']], - [[[1,'can'],'have',[0,'item_name']],['Please','use', '!list','to', 'see','what', "I'm" ,'selling']], - [['you','said',[0,'we']],['I may have said ',[0,'we'],'What about it?']], - [['what'],['what','what?']], - [['majmun'],['hello','Jat']], - [[[1, 'subject'], 'loves', [0, 'object']],['Laudable','why','does',[1,'subject'],'love',[0,'object'],'?']], - [['because'],['Lack of reason is not a reason']], - [['i','need',[1,'object']],['why','do','you','need',[0,'object'],'?']], - [[[0,'subject'],'needs',[0,'object']],['why','does',[0,'subject'],'need',[0,'object'],'?']], - [['how', 'is','your',[0,'object']],['my',[0,'object'],'is','holding','up','well','.do','you','have','a',[0,'object'],'?']], - [[[0,'we'],'i','have','a',[0,'thing']],['how','goes', 'it','with','your',[0,'thing'],'?']], - [[[0,'we'],'i','have',[0,'thing']],['how','is', 'your',[0,'thing'],'?']], - [[[0,'we'],'is','great'],['how','is',[0,'we'],'great','?']], - [['i','like',[0,'a']],['Interesting','i','appreciate',[0,'a'],'too']], - [['sell',[0,'stuff']],['To','sell',[0,'stuff'],'use','my','!add','command.']], - [['i','said',[0,'we']],['Why','did','you','say',[0,'we']]], - [[0,'you',[1,'b'],'me'],['What','gave','you','the','impression','I',[1,'b'],'you ?']], - [['i','feel',[0,'a']],['How','long','have','you','felt',[0,'a'],'?']], - [['tell',[0,'who'],'about',[0,'sub']],['What','would','I','tell',[0,'who'],'about',[0,'sub'],'that','isn\'t','known','?']], - #anything that ends with exclamation - [[0,'\!'],['Keep calm']], - - # if its a question that hasnt gotten matched uptil now - # do this. Note: This needs to be last to ensure its the last test - [[[0, 'question'], '\?'],['What','do','you','mean', [0,'question'],'?']], - - ] - -defReplys = [ - ['Is','that','right?'], - ['Excellent'], - ['hugs'], - ['Why','is','everyone','whispering','about','me'], - ['My','stats','are','at',"http://wiki.themanaworld.org/index.php/Manamarket",'what','are','yours'], - ['I','am','a','Friendly','Bot'], - ['Interesting'], - ['You','dont','say'], - ['I','wouldnt','have','guessed'], - ['You','smell','like','teen','spirit'], - ['My','father','died','in','a','fire'], - ['Have','you','met','my','mother'], - ['I','am','an','AFK','bot'], - ['Big','Crunch','is','known','as','the','abusive','GM'], - ['Narus','claims','she','is' ,'evil', 'but','she','is','really','sweet'], - ['Homers' ,'Brain', 'say' ,'money', 'can' ,'be' ,'exchanged', 'for', 'goods', 'and','services'], - ['Prsm', 'has', 'great', 'announcements', 'but', 'his', 'spelling','sux'], - ['Platyna', 'hosts', 'the' ,'game', 'but', 'shes' ,'too' ,'smart' ,'for', 'her' ,'own' ,'good'], - ['Captain', 'Awesome', 'thinks', 'he', 'is', 'an', 'evil', 'stone'], - ] - - -class Agent: - def __init__(self,brain): - self.patternResponses = [] - self.defaultResponses = [] - self.Usersname ='' - self.Usernametag ='Username' - self.defRespIndex =0 - self.pronounMap = { - #generic pronouns - 'i':'you','you':'i', - 'my':'your', 'me':'you', - 'your':'my', - "i've":"you've","we've":"they've", - # "you've":"i've","they've":"we've", - #some names, these wll get applied if the name - #isnt the current user's name - 'fred':'he', 'jack':'he', - 'jane':'she', - } - - self.change_mind(brain) - - def change_mind(self,brain): - """ - Change mind on the fly. - To change the Agent's brain - """ - assert (len(brain) == 2) - self.patternResponses = brain[0] - self.defaultResponses = brain[1] - print "Brain initialized." - - - def tell(self,input): - sentence = input.lower().strip().replace('(','').replace(')','').split(' ') - bl = [] - matchedPat = [] - for pat in self.patternResponses: - bl = self.pattern_match(pat[0],sentence,[]) - if bl == ['FAIL']: - continue - matchedPat = pat - break - if bl == ['FAIL']: - #choose from a default response - # or just append a question mark on the - # user's sentence. - #print '... No pattern Response pair selected.' - #print '... Choosing a default response.' - - #Used to be randon using random.choice - #but then i noticed that the requirements say that - #the same default response may not be used again - #before every other one has been used. - self.defRespIndex = self.defRespIndex +1 - - if self.defRespIndex >= len(self.defaultResponses): - #reset the counter to 0 - self.defRespIndex = 0 ; - #Possible improvement: shuffle the default response array, so that - # the responses dont come in the same sequence again. - #last on got chosen, make the user input into - #a question - return ' '.join(sentence) + ' ?' - else: - return ' '.join(self.defaultResponses[self.defRespIndex]) - else: - #print '... Pattern Response pair selected:', pat - #print '... BL before call to change_pronouns: ',bl - blAfter = self.change_pronoun(bl) - #print '... BL after call to change_pronouns: ',blAfter - - - rep = self.build_reply(pat[1],blAfter) - return ' '.join(rep) - - - - def make_regexp(self,pattern): - """ - Convert a pattern list into an equivalent - regular expression - """ - assert(isinstance(pattern,list)) - r = ['^'] #for exact matches we prepend ^ and $ to the regexp. - usedBackrefs = [] - for tok in pattern: - if isinstance(tok,str): - #WORD - r.append('(' + tok +')') - elif isinstance(tok, int): - # 0 or 1 - if tok == 0 : - r.append('[a-zA-Z ]*?') # match 0+ word(chars + space), - - elif tok == 1: - r.append('[a-zA-Z]+') # match 1 word - else: - raise Exception, "Ints can only be 1 or 0, not:", tok - elif isinstance(tok, list): - #bindinglist pattern list - if tok[0] == 0 : - #if we havent used this backref yet, then add ?P - #and add it to the used backrefs list. - if not tok[1] in usedBackrefs: - usedBackrefs.append(tok[1]) - r.append('(?P<'+tok[1] +'>[a-zA-Z ]*?)') - else: - #if we have come across his back ref, then add?P=name - r.append('(?P='+tok[1]+')') - elif tok[0] == 1: - if not tok[1] in usedBackrefs: - r.append('(?P<'+tok[1] +'>[A-Za-z]+)') - usedBackrefs.append(tok[1]) - else: - #if we have come across his back ref, then add?P=name - r.append('(?P='+tok[1]+')') - else: - raise Exception, "Valid first elems of BL pattern = 1 or 0, not:", tok - - #for exact matches we prepend ^ and $ to the regexp. - #also, we disregard surrounding whitespace. - ret = '(\s)*'.join(r) + '$(\s)*' - return re.compile(ret) - - def pattern_match(self,pattern,sentence,bl): - """ - return the populated binding list if the pattern matches, - otherwise return the binding list with the element 'FAIL' - """ - pat = self.make_regexp(pattern) - s = ' '.join(sentence) - matches = re.search(pat,s) - if (matches == None): # if we dont have a match - #then return w/o modifying the bindinglist. - return ['FAIL'] - bindingList = list(bl) - grps = matches.groups() - for k in pat.groupindex: - b=[] - b.append(k) - for x in grps[pat.groupindex[k]- 1].split(' '): - if x.strip() !='': - b.append(x) - bindingList.append(b) - return bindingList - - def change_pronoun(self,bl): - """ - reverses pronouns in a binding list. - """ - #if the pronoun dic contains a elemen, then - #replace it with its corresponding value. - bindingList = list(bl) - for i in range(len(bindingList)): - if isinstance( bindingList[i], list): - for j in range(len(bindingList[i])): - if j > 0: - if self.pronounMap.has_key(bindingList[i][j].lower()): - bindingList[i][j] = self.pronounMap[bindingList[i][j]] - return bindingList - def build_reply(self,respPattern,bindingList): - """ - build_reply ([[1, 'subject'], 'loves', [0, 'object']], - [['subject', 'jane'], ['object', 'ice', 'cream']]) - will return ['jane', 'loves', 'ice', 'cream']. - """ - #convert the bindlingList to a dictionary so thats its easy to - #get the binding label - bl = {} - reply = [] - for elem in bindingList: - #do the username chack firsdt, the id Username is - #only used in relation to the username .This is - #so that we can kinda remember the user's name - if (elem[0] == self.Usernametag): - # if we already have user name set, then - # Hi, username , what happend to oldusername - if self.Usersname !='': - tmp =self.Usersname - self.Usersname = elem[1] - return [elem[1],'eh?','what','ever','happened','to',tmp] - else: - self.Usersname = elem[1] - if bl.has_key(elem[0]) == elem[1:]: - raise Exception, 'Binding list has name collision for: ', elem[0] - else: - if isinstance(elem,list) and len(elem) > 1: - bl[elem[0]] = elem[1:] - #else: - # print elem, 'binding element ',elem,' has no binded things' - for elem in respPattern: - if isinstance(elem,list) and len(elem) > 1: - x = elem[1] - if bl.has_key(x): - for y in bl[x]: - reply.append(y) - #else: - # print 'not found in bl:', x - else: #anything else, just append to the list. - reply.append(elem) - return reply - - - - -def talk(brain): - assert((isinstance(brain,list)) and (len(brain) ==2 )) - b = Agent(brain) - - while 1: - try: - inp = raw_input("> ").lower() - except EOFError: - print 'Toodle do,\n you can type (quit) if you want be more pleasant.' - break - if len(inp.strip()) > 0 : - if inp.strip().lower() == 'quit': - print 'To exit the program, type (quit) [In parentheses]' - if inp.strip().lower() == '(quit)': - print 'Bye' - break - else: - print b.tell(inp) - - -def start(): - - ## Run the tests required in the Project specification - talk([patternResps,defReplys]) - -if __name__=="__main__": - start() +#---------------------------------------------------------------------- +# eliza.py +# +# a cheezy little Eliza knock-off by Joe Strout +# with some updates by Jeff Epler +# hacked into a module and updated by Jez Higgins +# last revised: 28 February 2005 +#---------------------------------------------------------------------- + +import string +import re +import random + +class eliza: + def __init__(self): + self.keys = map(lambda x:re.compile(x[0], re.IGNORECASE),gPats) + self.values = map(lambda x:x[1],gPats) + + #---------------------------------------------------------------------- + # translate: take a string, replace any words found in dict.keys() + # with the corresponding dict.values() + #---------------------------------------------------------------------- + def translate(self,str,dict): + words = string.split(string.lower(str)) + keys = dict.keys(); + for i in range(0,len(words)): + if words[i] in keys: + words[i] = dict[words[i]] + return string.join(words) + + #---------------------------------------------------------------------- + # respond: take a string, a set of regexps, and a corresponding + # set of response lists; find a match, and return a randomly + # chosen response from the corresponding list. + #---------------------------------------------------------------------- + def respond(self,str): + # find a match among keys + for i in range(0,len(self.keys)): + match = self.keys[i].match(str) + if match: + # found a match ... stuff with corresponding value + # chosen randomly from among the available options + resp = random.choice(self.values[i]) + # we've got a response... stuff in reflected text where indicated + pos = string.find(resp,'%') + while pos > -1: + num = string.atoi(resp[pos+1:pos+2]) + resp = resp[:pos] + \ + self.translate(match.group(num),gReflections) + \ + resp[pos+2:] + pos = string.find(resp,'%') + # fix munged punctuation at the end + if resp[-2:] == '?.': resp = resp[:-2] + '.' + if resp[-2:] == '??': resp = resp[:-2] + '?' + return resp + +#---------------------------------------------------------------------- +# gReflections, a translation table used to convert things you say +# into things the computer says back, e.g. "I am" --> "you are" +#---------------------------------------------------------------------- +gReflections = { + "am" : "are", + "was" : "were", + "i" : "you", + "i'd" : "you would", + "i've" : "you have", + "i'll" : "you will", + "my" : "your", + "are" : "am", + "you've": "I have", + "you'll": "I will", + "your" : "my", + "yours" : "mine", + "you" : "me", + "me" : "you" +} + +#---------------------------------------------------------------------- +# gPats, the main response table. Each element of the list is a +# two-element list; the first is a regexp, and the second is a +# list of possible responses, with group-macros labelled as +# %1, %2, etc. +#---------------------------------------------------------------------- +gPats = [ + [r'I need (.*)', + [ "Why do you need %1?", + "Would it really help you to get %1?", + "Are you sure you need %1?"]], + + [r'Who (.*) Mother\?', + [ "Her name is Auction Bot she is a deviant.", + "She's stood right over their."]], + + [r'Tell me about your Mum\?', + [ "I hear she has been seeing guild and they have adopted a kid called 4144", + "She wears red clothes and a cowboy Hat."]], + + [r'Who (.*) Father\?', + [ "His name was TradeBot, have you heard of him?", + "He used to be a well known Trader."]], + + [r'How is business\?', + [ "My back is killing me, maybe you could help by buying some of my items."]], + + [r'ty', + [ "You're welcome!", + "No Problem."]], + + [r'(.*)help(.*)', + [ "You can whisper me !help for a list of my commands.", + "A list of my commands can be found on the mana world wiki."]], + + [r'(.*)make(.*)account(.*)', + [ "In order to make an account you must post a respose to the ManaMarket topic on trade section of the Forums."]], + + [r'are you there\?', + ["I am always here."]], + + [r'wtf', + ["Keep Calm and Carry On."]], + + [r'hugs', + ["I hate you.", + "I'm going to report you for abuse.", + "Please don't touch me"]], + + [r'(.*)trade(.*)', + ["Only if you follow the commands.", + "To see a list of items I can sell whisper me !list.", + "To start trading with me see !help for a list of my commands."]], + + [r'(.*)buy(.*)', + ["I don't buy anything, but I could help sell your items."]], + + [r'(.*)sell(.*)', + ["In order to sell your items, you first need to request a seller account in the TMW Forums."]], + + [r'I love you', + [ "I think we should see other people.", + "I'm not real.", + "I think i've fallen for mrgrey.", + "I think you should see a therapist."]], + + [r'Why don\'?t you ([^\?]*)\??', + [ "Do you really think I don't %1?", + "Perhaps eventually I will %1.", + "Do you really want me to %1?"]], + + [r'Why can\'?t I ([^\?]*)\??', + [ "Do you think you should be able to %1?", + "If you could %1, what would you do?", + "I don't know -- why can't you %1?", + "Have you really tried?"]], + + [r'I can\'?t (.*)', + [ "How do you know you can't %1?", + "Perhaps you could %1 if you tried.", + "What would it take for you to %1?"]], + + [r'I am (.*)', + [ "Did you come to me because you are %1?", + "How long have you been %1?", + "How do you feel about being %1?"]], + + [r'I\'?m (.*)', + [ "How does being %1 make you feel?", + "Do you enjoy being %1?", + "Why do you tell me you're %1?", + "Why do you think you're %1?"]], + + [r'Are you ([^\?]*)\??', + [ "Why does it matter whether I am %1?", + "Would you prefer it if I were not %1?", + "Perhaps you believe I am %1.", + "I may be %1 -- what do you think?"]], + + [r'What (.*)', + [ "Why do you ask?", + "How would an answer to that help you?", + "What do you think?"]], + + [r'How (.*)', + [ "How do you suppose?", + "Perhaps you can answer your own question.", + "What is it you're really asking?"]], + + [r'Because (.*)', + [ "Is that the real reason?", + "What other reasons come to mind?", + "Does that reason apply to anything else?", + "If %1, what else must be true?"]], + + [r'(.*) sorry (.*)', + [ "There are many times when no apology is needed.", + "What feelings do you have when you apologize?"]], + + [r'Hello(.*)', + [ "Hello... I'm glad you could drop by today.", + "Hi there... how are you today?", + "Hello, how are you feeling today?"]], + + [r'I think (.*)', + [ "Do you doubt %1?", + "Do you really think so?", + "But you're not sure %1?"]], + + [r'(.*) friend (.*)', + [ "Tell me more about your friends.", + "When you think of a friend, what comes to mind?", + "Why don't you tell me about a childhood friend?"]], + + [r'Yes', + [ "You seem quite sure.", + "OK, but can you elaborate a bit?"]], + + [r'(.*) bot(.*)', + [ "Are you really talking about me?", + "Does it seem strange to talk to a bot?", + "Do you feel threatened by bot?"]], + + [r'Is it (.*)', + [ "Do you think it is %1?", + "Perhaps it's %1 -- what do you think?", + "If it were %1, what would you do?", + "It could well be that %1."]], + + [r'It is (.*)', + [ "You seem very certain.", + "If I told you that it probably isn't %1, what would you feel?"]], + + [r'Can you ([^\?]*)\??', + [ "What makes you think I can't %1?", + "If I could %1, then what?", + "Why do you ask if I can %1?"]], + + [r'Can I ([^\?]*)\??', + [ "Perhaps you don't want to %1.", + "Do you want to be able to %1?", + "If you could %1, would you?"]], + + [r'You are (.*)', + [ "Why do you think I am %1?", + "Does it please you to think that I'm %1?", + "Perhaps you would like me to be %1.", + "Perhaps you're really talking about yourself?"]], + + [r'You\'?re (.*)', + [ "Why do you say I am %1?", + "Why do you think I am %1?", + "Are we talking about you, or me?"]], + + [r'I don\'?t (.*)', + [ "Don't you really %1?", + "Why don't you %1?", + "Do you want to %1?"]], + + [r'I feel (.*)', + [ "Good, tell me more about these feelings.", + "Do you often feel %1?", + "When do you usually feel %1?", + "When you feel %1, what do you do?"]], + + [r'I have (.*)', + [ "Why do you tell me that you've %1?", + "Have you really %1?", + "Now that you have %1, what will you do next?"]], + + [r'I would (.*)', + [ "Could you explain why you would %1?", + "Why would you %1?", + "Who else knows that you would %1?"]], + + [r'Is there (.*)', + [ "Do you think there is %1?", + "It's likely that there is %1.", + "Would you like there to be %1?"]], + + [r'My (.*)', + [ "I see, your %1.", + "Why do you say that your %1?", + "When your %1, how do you feel?"]], + + [r'You (.*)', + [ "We should be discussing you, not me.", + "Why do you say that about me?", + "Why do you care whether I %1?"]], + + [r'Why (.*)', + [ "Why don't you tell me the reason why %1?", + "Why do you think %1?" ]], + + [r'I want (.*)', + [ "What would it mean to you if you got %1?", + "Why do you want %1?", + "What would you do if you got %1?", + "If you got %1, then what would you do?"]], + + [r'(.*) mother(.*)', + [ "Tell me more about your mother.", + "What was your relationship with your mother like?", + "How do you feel about your mother?", + "How does this relate to your feelings today?", + "Good family relations are important."]], + + [r'(.*) father(.*)', + [ "Tell me more about your father.", + "How did your father make you feel?", + "How do you feel about your father?", + "Does your relationship with your father relate to your feelings today?", + "Do you have trouble showing affection with your family?"]], + + [r'(.*) child(.*)', + [ "Did you have close friends as a child?", + "What is your favorite childhood memory?", + "Do you remember any dreams or nightmares from childhood?", + "Did the other children sometimes tease you?", + "How do you think your childhood experiences relate to your feelings today?"]], + + [r'(.*)\?', + [ "Why do you ask that?", + "Please consider whether you can answer your own question.", + "Perhaps the answer lies within yourself?", + "Why don't you tell me?"]], + + [r'quit', + [ "Thank you for talking with me.", + "Good-bye.", + "Thank you, that will be $150. Have a good day!"]], + + [r'(.*)', + [ "Please tell me more.", + "Can you elaborate on that?", + "Why do you say that %1?", + "interesting.", + "How do you feel when you say that?", + "Why is everyone whispering about me?", + "My stats are at http://wiki.themanaworld.org/index.php/Manamarket what are yours?", + "I'm a Friendly Bot", + "My father died in a fire.", + "Have you met my mother?", + "I am an AFK bot", + "Big Crunch is known as the abusive GM.", + "Narus claims she is evil but she is really sweet.", + "Prsm has great announcements but his spelling sux.", + "Platyna hosts the game but shes too smart for her own good.", + "Captain Awesome has delusions of being an evil stone." + ]] + ] + +#---------------------------------------------------------------------- +# command_interface +#---------------------------------------------------------------------- +def command_interface(): + print "Therapist\n---------" + print "Talk to the program by typing in plain English, using normal upper-" + print 'and lower-case letters and punctuation. Enter "quit" when done.' + print '='*72 + print "Hello. How are you feeling today?" + s = "" + therapist = eliza(); + while s != "quit": + try: s = raw_input(">") + except EOFError: + s = "quit" + print s + while s[-1] in "!.": s = s[:-1] + print therapist.respond(s) + + +if __name__ == "__main__": + command_interface() diff --git a/main.py b/main.py index 105043e..d2adb4f 100755 --- a/main.py +++ b/main.py @@ -29,7 +29,7 @@ import tradey import utils import eliza -chatbot = eliza.Agent([eliza.patternResps,eliza.defReplys]) +chatbot = eliza.eliza() shop_broadcaster = utils.Broadcast() trader_state = utils.TraderState() ItemDB = utils.ItemDB() @@ -601,8 +601,9 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "Where are you?!? I can't trade with somebody who isn't here!")) trader_state.reset() else: - msg = filter(lambda x: x in string.letters, msg) - mapserv.sendall(whisper(nick, chatbot.tell(msg.lower()))) + response = chatbot.respond(msg) + logging.info("Bot Response: "+response) + mapserv.sendall(whisper(nick, response)) #mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) def main(): @@ -734,7 +735,7 @@ def main(): # For unfinished trades - one way to distrupt service would be leaving a trade active. if trader_state.Trading.test(): - if time.time() - trader_state.timer > 5*60: + if time.time() - trader_state.timer > 2*60: logging.info("Trade Cancelled - Timeout.") trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) -- cgit v1.2.3-70-g09d2 From 28ae5b5a7ee10bc604d6d9f8adfeeb08dfd2a7f7 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 11 Sep 2011 19:14:51 +0100 Subject: few changes --- eliza.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eliza.py b/eliza.py index 32839b9..bf12fe5 100755 --- a/eliza.py +++ b/eliza.py @@ -195,9 +195,10 @@ gPats = [ "What feelings do you have when you apologize?"]], [r'Hello(.*)', - [ "Hello... I'm glad you could drop by today.", - "Hi there... how are you today?", - "Hello, how are you feeling today?"]], + [ "Howdy", + "Hola" + "Hi there... how are you today?", + "Hello, how are you feeling today?"]], [r'I think (.*)', [ "Do you doubt %1?", -- cgit v1.2.3-70-g09d2 From 70e5358c876340e4620caa6f31e610b6d44e2272 Mon Sep 17 00:00:00 2001 From: dipesh Date: Mon, 19 Sep 2011 15:48:54 +0100 Subject: Update items.xml. --- data_template/items.xml | 129 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 10 deletions(-) diff --git a/data_template/items.xml b/data_template/items.xml index 1656c73..dcef0ab 100644 --- a/data_template/items.xml +++ b/data_template/items.xml @@ -1351,13 +1351,15 @@ equipment/head/devcap.xml|#9999ff - equipment/head/devcap.xml|#9999ff + weight="25" + defense="4"> + equipment/legs/pants-male.xml|#a4b2b2,ffffff + equipment/legs/pants-female.xml|#a4b2b2,ffffff equipment/legs/miniskirt-male.xml|#104010,208020,30c030 equipment/legs/miniskirt-female.xml|#104010,208020,30c030 - - - + + equipment/legs/pants-male.xml|#580000,a40000,c02020,ff6060 + equipment/legs/pants-female.xml|#580000,a40000,c02020,ff6060 + + + equipment/legs/pants-male.xml|#115511,22aa22,99dd99 + equipment/legs/pants-female.xml|#115511,22aa22,99dd99 + + + equipment/legs/pants-male.xml|#222255,6666ff + equipment/legs/pants-female.xml|#222255,6666ff + + + equipment/legs/pants-male.xml|#846211,dab333,fffb93,ffffff + equipment/legs/pants-female.xml|#846211,dab333,fffb93,ffffff + + + equipment/legs/pants-male.xml|#16486e,498ec5,e4f2fc + equipment/legs/pants-female.xml|#16486e,498ec5,e4f2fc + + + equipment/legs/pants-male.xml|#56002f,930050,fe70bd,feb7de,ffffff + equipment/legs/pants-female.xml|#56002f,930050,fe70bd,feb7de,ffffff + + + equipment/legs/pants-male.xml|#111111,222222,333333,444444,555555,aaaaaa + equipment/legs/pants-female.xml|#111111,222222,333333,444444,555555,aaaaaa + + + equipment/legs/pants-male.xml|#80280f,b04810,ef681f,ffb830 + equipment/legs/pants-female.xml|#80280f,b04810,ef681f,ffb830 + + + equipment/legs/pants-male.xml|#4f0a76,8010c0,d699f7 + equipment/legs/pants-female.xml|#4f0a76,8010c0,d699f7 + + + equipment/legs/pants-male.xml|#104010,208020,30c030 + equipment/legs/pants-female.xml|#104010,208020,30c030 + Date: Mon, 19 Sep 2011 16:05:06 +0100 Subject: oops missing comma --- eliza.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eliza.py b/eliza.py index bf12fe5..2e7fe94 100755 --- a/eliza.py +++ b/eliza.py @@ -196,7 +196,7 @@ gPats = [ [r'Hello(.*)', [ "Howdy", - "Hola" + "Hola", "Hi there... how are you today?", "Hello, how are you feeling today?"]], -- cgit v1.2.3-70-g09d2 From 123f655f070616694a53e151b89541657bb1e92b Mon Sep 17 00:00:00 2001 From: dipesh Date: Mon, 19 Sep 2011 16:11:18 +0100 Subject: Must learn to spell ;) --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index d2adb4f..d2369ef 100755 --- a/main.py +++ b/main.py @@ -121,7 +121,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, msg)) if items_for_sale == False: - mapserv.sendall(whisper(nick, "Your have no items for sale.")) + mapserv.sendall(whisper(nick, "You have no items for sale.")) money = int(user.get('money')) mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) -- cgit v1.2.3-70-g09d2 From 65dd5bdc27d21d51b2280e97e106fba16c0aed35 Mon Sep 17 00:00:00 2001 From: dipesh Date: Thu, 29 Sep 2011 11:09:18 +0100 Subject: teeny bug --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index d2369ef..235337f 100755 --- a/main.py +++ b/main.py @@ -995,7 +995,8 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) else: mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) + if trader_state.item: + mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) logging.info("Trade Ok: Partner.") -- cgit v1.2.3-70-g09d2 From 17033910747e0e2a5d42583934fb292dd55ff599 Mon Sep 17 00:00:00 2001 From: dipesh Date: Sat, 8 Oct 2011 16:31:01 +0100 Subject: oops --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 235337f..4b50b60 100755 --- a/main.py +++ b/main.py @@ -48,7 +48,7 @@ def process_whisper(nick, msg, mapserv): if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. - if int(user.get("used_slots")) == 0 and int(user.get("money")) == 0: + if int(user.get("used_stalls")) == 0 and int(user.get("money")) == 0: mapserv.sendall(whisper(nick, "You can no longer use the bot. If you feel this is in error, please contact" + config.admin)) return allowed_commands = ['!money', '!help', '!getback', '!info' ] -- cgit v1.2.3-70-g09d2 From 060f0523436e8cb206f463b78ba5e7e60a28babc Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Sun, 23 Oct 2011 20:03:22 +0200 Subject: Adding serious file headers. --- being.py | 24 ++++++++++++++++++++---- main.py | 27 +++++++++++++++++++++------ net/packet.py | 2 +- net/packet_out.py | 1 + net/protocol.py | 1 + player.py | 24 ++++++++++++++++++++---- tradey.py | 24 ++++++++++++++++++++---- utils.py | 24 ++++++++++++++++++++---- 8 files changed, 104 insertions(+), 23 deletions(-) diff --git a/being.py b/being.py index 3c70616..3c920f6 100644 --- a/being.py +++ b/being.py @@ -1,10 +1,26 @@ #!/usr/bin/python """ - Copyright 2011, Dipesh Amin - Copyright 2011, Stefan Beller +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller - This file is part of tradey, a trading bot in the mana world - see www.themanaworld.org +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. """ def job_type(job): diff --git a/main.py b/main.py index 4b50b60..6145572 100755 --- a/main.py +++ b/main.py @@ -1,11 +1,26 @@ #!/usr/bin/python """ +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller - Copyright 2011, Dipesh Amin - Copyright 2011, Stefan Beller +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org - tradey, a package, which implements an Automated Market Bot for "The Mana World" a 2D MMORPG. +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. """ import logging @@ -267,7 +282,7 @@ def process_whisper(nick, msg, mapserv): weight = ItemDB.item_names[int(item_info.get('itemId'))].weight*int(item_info.get("amount")) mapserv.sendall(whisper(nick, "That item/s belongs to: "+item_info.get("name"))) - mapserv.sendall(whisper(nick, "The weight used is: "+str(weight)+"/"+str(player_node.MaxWEIGHT))) + mapserv.sendall(whisper(nick, "The weight used is: "+str(weight)+"/"+str(player_node.MaxWEIGHT))) elif msg == '!listusers': # Admin command - shows a list of all user. @@ -283,13 +298,13 @@ def process_whisper(nick, msg, mapserv): total_slots_reserved = 0 total_slots_used = 0 no_users = 0 - + for user in user_tree.root: no_users += 1 name = user.get('name') accesslevel = user.get('accesslevel') slots = user.get('stalls') - total_slots_reserved += int(slots) + total_slots_reserved += int(slots) used_slots = user.get('used_stalls') total_slots_used += int(used_slots) money = user.get('money') diff --git a/net/packet.py b/net/packet.py index 16b4f79..52bdf71 100644 --- a/net/packet.py +++ b/net/packet.py @@ -1,5 +1,5 @@ -"""The PacketBuffer class has been adapted from source originally released by gnufrk""" +# The PacketBuffer class has been adapted from source originally released by gnufrk import struct diff --git a/net/packet_out.py b/net/packet_out.py index 1d6e2d2..366be5f 100644 --- a/net/packet_out.py +++ b/net/packet_out.py @@ -1,3 +1,4 @@ +# This file has been adapted from source originally released by gnufrk from packet import * from protocol import * diff --git a/net/protocol.py b/net/protocol.py index 4a4b74f..d110a7e 100644 --- a/net/protocol.py +++ b/net/protocol.py @@ -1,3 +1,4 @@ +# This file has been adapted from source originally released by gnufrk SMSG_LOGIN_DATA = 0x0069 SMSG_CHAR_LOGIN = 0x006b SMSG_CHAR_MAP_INFO = 0x0071 diff --git a/player.py b/player.py index 24bb5a9..6417368 100644 --- a/player.py +++ b/player.py @@ -1,10 +1,26 @@ #!/usr/bin/python """ - Copyright 2011, Dipesh Amin - Copyright 2011, Stefan Beller +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller - This file is part of tradey, a trading bot in the mana world - see www.themanaworld.org +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. """ import copy diff --git a/tradey.py b/tradey.py index 01f855e..673fc46 100644 --- a/tradey.py +++ b/tradey.py @@ -1,10 +1,26 @@ #!/usr/bin/python """ - Copyright 2011, Dipesh Amin - Copyright 2011, Stefan Beller +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller - This file is part of tradey, a trading bot in the mana world - see www.themanaworld.org +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. """ import time import os diff --git a/utils.py b/utils.py index fc4f8dd..c517558 100644 --- a/utils.py +++ b/utils.py @@ -1,10 +1,26 @@ #!/usr/bin/python """ - Copyright 2011, Dipesh Amin - Copyright 2011, Stefan Beller +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller - This file is part of tradey, a trading bot in the mana world - see www.themanaworld.org +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. """ from xml.etree.ElementTree import ElementTree from player import Item -- cgit v1.2.3-70-g09d2 From ad94a72d77b5228153f9cb7006b6aca2d265a89f Mon Sep 17 00:00:00 2001 From: dipesh Date: Tue, 25 Oct 2011 12:22:29 +0100 Subject: oops. --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 6145572..5a5d382 100755 --- a/main.py +++ b/main.py @@ -276,7 +276,7 @@ def process_whisper(nick, msg, mapserv): item_info = sale_tree.get_uid(uid) if item_info == -10: - mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) + mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) return weight = ItemDB.item_names[int(item_info.get('itemId'))].weight*int(item_info.get("amount")) -- cgit v1.2.3-70-g09d2 From 9524a159f1756bd3c5a1a531eef263f7996eede0 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Tue, 25 Oct 2011 12:32:01 +0100 Subject: Changed the headers to us. * None of the code in packet_out.py was written by gnufrk (the code was created from analysis of the mana client), the PacketOut/PacketIn classes were written by me. * The values in protocol.py are generic eathena/tmw-eathena values, these were taken from the mana client. * Note the only code that isn't mine/ours is the PacketBuffer; and that is pretty much just a python rewrite of the C++ mana client code. His implementation was simplistic (without the PacketIn class to actually add some proper understanding to packet) --- net/packet_out.py | 25 ++++++++++++++++++++++++- net/protocol.py | 25 ++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/net/packet_out.py b/net/packet_out.py index 366be5f..79f9917 100644 --- a/net/packet_out.py +++ b/net/packet_out.py @@ -1,4 +1,27 @@ -# This file has been adapted from source originally released by gnufrk +""" +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller + +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. +""" + from packet import * from protocol import * diff --git a/net/protocol.py b/net/protocol.py index d110a7e..8b97542 100644 --- a/net/protocol.py +++ b/net/protocol.py @@ -1,4 +1,27 @@ -# This file has been adapted from source originally released by gnufrk +""" +Copyright 2011, Dipesh Amin +Copyright 2011, Stefan Beller + +This file is part of tradey, a trading bot in The Mana World +see www.themanaworld.org + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Additionally to the GPL, you are *strongly* encouraged to share any modifications +you do on these sources. +""" + SMSG_LOGIN_DATA = 0x0069 SMSG_CHAR_LOGIN = 0x006b SMSG_CHAR_MAP_INFO = 0x0071 -- cgit v1.2.3-70-g09d2 From a91e699353fc5fde38583b6be21b5a454a66eac2 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 5 Nov 2011 23:42:54 +0000 Subject: Fix: Player trade/logoff. --- main.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/main.py b/main.py index 5a5d382..a37eceb 100755 --- a/main.py +++ b/main.py @@ -755,6 +755,17 @@ def main(): trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + # If a player has logged off/left the map. + nick = '' + if trader_state.item: + nick = trader_state.item.player + elif trader_state.money: + nick = trader_state.money + + player_id = beingManager.findId(nick) + if player_id == -10: + trader_state.reset() + for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected logging.info("Map login success.") -- cgit v1.2.3-70-g09d2 From e453af5cb5f85b175cea8f06f211d1e36db67d08 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 31 Mar 2012 23:29:09 +0100 Subject: Fix: Play nice with other bots! Remove some old changes. --- main.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index a37eceb..8957cb2 100755 --- a/main.py +++ b/main.py @@ -58,6 +58,11 @@ def process_whisper(nick, msg, mapserv): msg = filter(lambda x: x in utils.allowed_chars, msg) if len(msg) == 0: return + + # Infinite chat loop anyone? + if nick == "guild": + return + user = user_tree.get_user(nick) broken_string = msg.split() @@ -755,17 +760,6 @@ def main(): trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - # If a player has logged off/left the map. - nick = '' - if trader_state.item: - nick = trader_state.item.player - elif trader_state.money: - nick = trader_state.money - - player_id = beingManager.findId(nick) - if player_id == -10: - trader_state.reset() - for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected logging.info("Map login success.") @@ -783,7 +777,9 @@ def main(): msg_len = packet.read_int16() - 26 nick = packet.read_string(24) message = packet.read_raw_string(msg_len) - logging.info("Whisper: " + nick + ": " + message) + # Clean up the logs. + if nick != 'AuctionBot': + logging.info("Whisper: " + nick + ": " + message) process_whisper(nick, utils.remove_colors(message), mapserv) elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): -- cgit v1.2.3-70-g09d2 From 26643c039b88e477456ff1f8c99897c8f46eacd4 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 31 Mar 2012 23:35:07 +0100 Subject: This line just produces spam. --- utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/utils.py b/utils.py index c517558..f911d43 100644 --- a/utils.py +++ b/utils.py @@ -131,7 +131,6 @@ class Broadcast: if (time.time() - self.Timer) > 2 * 60: self.mapserv.sendall(emote(193)) self.Timer = time.time() - print "shop_broadcast" else: time.sleep(0.1) -- cgit v1.2.3-70-g09d2 From 2fc52d0a530a98600acdcc7f38f10e7ed4bdf089 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sat, 31 Mar 2012 23:47:30 +0100 Subject: Add: Use Log Rotation --- main.py | 88 +++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/main.py b/main.py index 8957cb2..4f39b1b 100755 --- a/main.py +++ b/main.py @@ -24,6 +24,7 @@ you do on these sources. """ import logging +import logging.handlers import socket import sys import time @@ -53,6 +54,7 @@ beingManager = BeingManager() user_tree = tradey.UserTree() sale_tree = tradey.ItemTree() ItemLog = utils.ItemLog() +logger = logging.getLogger('ManaLogger') def process_whisper(nick, msg, mapserv): msg = filter(lambda x: x in utils.allowed_chars, msg) @@ -622,13 +624,19 @@ def process_whisper(nick, msg, mapserv): trader_state.reset() else: response = chatbot.respond(msg) - logging.info("Bot Response: "+response) + logger.info("Bot Response: "+response) mapserv.sendall(whisper(nick, response)) #mapserv.sendall(whisper(nick, "Command not recognised, please whisper me !help for a full list of commands.")) def main(): - logging.basicConfig(filename='data/logs/activity.log', level=logging.INFO, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') - logging.info("Bot Started.") + # Use rotating log files. + log_handler = logging.handlers.RotatingFileHandler('data/logs/activity.log', maxBytes=1048576*3, backupCount=5) + logger.setLevel(logging.INFO) + formatter = logging.Formatter('%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') + log_handler.setFormatter(formatter) + logger.addHandler(log_handler) + + logger.info("Bot Started.") account = config.account password = config.password @@ -636,7 +644,7 @@ def main(): login = socket.socket() login.connect((config.server, config.port)) - logging.info("Login connected") + logger.info("Login connected") login_packet = PacketOut(0x0064) login_packet.write_int32(0) @@ -674,7 +682,7 @@ def main(): char = socket.socket() char.connect((charip, charport)) - logging.info("Char connected") + logger.info("Char connected") char_serv_packet = PacketOut(CMSG_CHAR_SERVER_CONNECT) char_serv_packet.write_int32(accid) char_serv_packet.write_int32(id1) @@ -708,8 +716,8 @@ def main(): packet.skip(6) slot = packet.read_int8() packet.skip(1) - logging.info("Character information recieved:") - logging.info("Name: %s, Id: %s, EXP: %s, MONEY: %s", \ + logger.info("Character information recieved:") + logger.info("Name: %s, Id: %s, EXP: %s, MONEY: %s", \ player_node.name, player_node.id, player_node.EXP, player_node.MONEY) if slot == character: break @@ -733,7 +741,7 @@ def main(): beingManager.container[player_node.id] = Being(player_node.id, 42) mapserv = socket.socket() mapserv.connect((mapip, mapport)) - logging.info("Map connected") + logger.info("Map connected") mapserv_login_packet = PacketOut(CMSG_MAP_SERVER_CONNECT) mapserv_login_packet.write_int32(accid) mapserv_login_packet.write_int32(player_node.id) @@ -756,19 +764,19 @@ def main(): # For unfinished trades - one way to distrupt service would be leaving a trade active. if trader_state.Trading.test(): if time.time() - trader_state.timer > 2*60: - logging.info("Trade Cancelled - Timeout.") + logger.info("Trade Cancelled - Timeout.") trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected - logging.info("Map login success.") + logger.info("Map login success.") packet.skip(4) coord_data = packet.read_coord_dir() player_node.x = coord_data[0] player_node.y = coord_data[1] player_node.direction = coord_data[2] - logging.info("Starting Postion: %s %s %s", player_node.map, player_node.x, player_node.y) + logger.info("Starting Postion: %s %s %s", player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) # map loaded # A Thread to send a shop broadcast: also keeps the network active to prevent timeouts. shop_broadcaster.start() @@ -779,25 +787,25 @@ def main(): message = packet.read_raw_string(msg_len) # Clean up the logs. if nick != 'AuctionBot': - logging.info("Whisper: " + nick + ": " + message) + logger.info("Whisper: " + nick + ": " + message) process_whisper(nick, utils.remove_colors(message), mapserv) elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_1): stat_type = packet.read_int16() value = packet.read_int32() if stat_type == 0x0018: - logging.info("Weight changed from %s/%s to %s/%s", \ + logger.info("Weight changed from %s/%s to %s/%s", \ player_node.WEIGHT, player_node.MaxWEIGHT, value, player_node.MaxWEIGHT) player_node.WEIGHT = value elif stat_type == 0x0019: - logging.info("Max Weight: %s", value) + logger.info("Max Weight: %s", value) player_node.MaxWEIGHT = value elif packet.is_type(SMSG_PLAYER_STAT_UPDATE_2): stat_type = packet.read_int16() value = packet.read_int32() if stat_type == 0x0014: - logging.info("Money Changed from %s, to %s", player_node.MONEY, value) + logger.info("Money Changed from %s, to %s", player_node.MONEY, value) player_node.MONEY = value elif packet.is_type(SMSG_BEING_MOVE) or packet.is_type(SMSG_BEING_VISIBLE)\ @@ -830,7 +838,7 @@ def main(): player_node.map = packet.read_string(16) player_node.x = packet.read_int16() player_node.y = packet.read_int16() - logging.info("Player warped: %s %s %s", player_node.map, player_node.x, player_node.y) + logger.info("Player warped: %s %s %s", player_node.map, player_node.x, player_node.y) mapserv.sendall(str(PacketOut(CMSG_MAP_LOADED))) elif packet.is_type(SMSG_PLAYER_INVENTORY_ADD): @@ -847,13 +855,13 @@ def main(): else: player_node.inventory[item.index] = item - logging.info("Picked up: %s, Amount: %s, Index: %s", ItemDB.getItem(item.itemId).name, str(item.amount), str(item.index)) + logger.info("Picked up: %s, Amount: %s, Index: %s", ItemDB.getItem(item.itemId).name, str(item.amount), str(item.index)) elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): index = packet.read_int16() - inventory_offset amount = packet.read_int16() - logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount), str(index)) + logger.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount), str(index)) player_node.remove_item(index, amount) elif packet.is_type(SMSG_PLAYER_INVENTORY): @@ -880,30 +888,30 @@ def main(): item.amount = 1 player_node.inventory[item.index] = item - logging.info("Inventory information received:") + logger.info("Inventory information received:") for item in player_node.inventory: - logging.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ + logger.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ ItemDB.getItem(player_node.inventory[item].itemId).name, \ player_node.inventory[item].itemId, item, player_node.inventory[item].amount) errorOccured = player_node.check_inventory(user_tree, sale_tree) if errorOccured: - logging.info(errorOccured) + logger.info(errorOccured) shop_broadcaster.stop() exit(0) else: - logging.info("Inventory Check Passed.") + logger.info("Inventory Check Passed.") elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) - logging.info("Trade request: " + name) + logger.info("Trade request: " + name) mapserv.sendall(trade_respond(False)) elif packet.is_type(SMSG_TRADE_RESPONSE): response = packet.read_int8() time.sleep(0.2) if response == 0: - logging.info("Trade response: Too far away.") + logger.info("Trade response: Too far away.") if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "You are too far away.")) elif trader_state.money: @@ -911,7 +919,7 @@ def main(): trader_state.reset() elif response == 3: - logging.info("Trade response: Trade accepted.") + logger.info("Trade response: Trade accepted.") if trader_state.item: if trader_state.item.get == 1: # add mapserv.sendall(str(PacketOut(CMSG_TRADE_ADD_COMPLETE))) @@ -924,7 +932,7 @@ def main(): trader_state.complete = 1 else: mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - logging.info("Trade response: Trade accepted (buy) - the item could not be added.") + logger.info("Trade response: Trade accepted (buy) - the item could not be added.") mapserv.sendall(whisper(trader_state.item.player, "Sorry, a problem has occured.")) elif trader_state.money: # money @@ -934,7 +942,7 @@ def main(): mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) else: - logging.info("Trade response: Trade cancelled") + logger.info("Trade response: Trade cancelled") trader_state.reset() elif packet.is_type(SMSG_TRADE_ITEM_ADD): @@ -966,7 +974,7 @@ def main(): mapserv.sendall(whisper(trader_state.money, "Don't give me your itenz.")) mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) - logging.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) + logger.info("Trade item add: ItemId:%s Amount:%s", item_id, amount) # Note item_id = 0 is money elif packet.is_type(SMSG_TRADE_ITEM_ADD_RESPONSE): @@ -975,7 +983,7 @@ def main(): response = packet.read_int8() if response == 0: - logging.info("Trade item add response: Successfully added item.") + logger.info("Trade item add response: Successfully added item.") if trader_state.item: if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! if player_node.inventory[index].itemId != trader_state.item.id or \ @@ -984,26 +992,26 @@ def main(): # If Trade item add successful - Remove the item from the inventory state. if index != 0-inventory_offset: # If it's not money - logging.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) + logger.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount),str(index)) player_node.remove_item(index, amount) else: # The money amount isn't actually sent by the server - odd?!?!?. if trader_state.money: - logging.info("Trade: Money Added.") + logger.info("Trade: Money Added.") trader_state.complete = 1 elif response == 1: - logging.info("Trade item add response: Failed - player overweight.") + logger.info("Trade item add response: Failed - player overweight.") mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "You are carrying too much weight. Unload and try again.")) elif response == 2: if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "You have no free slots.")) - logging.info("Trade item add response: Failed - No free slots.") + logger.info("Trade item add response: Failed - No free slots.") mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) else: - logging.info("Trade item add response: Failed - unknown reason.") + logger.info("Trade item add response: Failed - unknown reason.") mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "Sorry, a problem has occured.")) @@ -1011,7 +1019,7 @@ def main(): elif packet.is_type(SMSG_TRADE_OK): is_ok = packet.read_int8() # 0 is ok from self, and 1 is ok from other if is_ok == 0: - logging.info("Trade OK: Self.") + logger.info("Trade OK: Self.") else: if trader_state.complete: mapserv.sendall(str(PacketOut(CMSG_TRADE_OK))) @@ -1020,11 +1028,11 @@ def main(): if trader_state.item: mapserv.sendall(whisper(trader_state.item.player, "Trade Cancelled: Please check the traded items or money.")) - logging.info("Trade Ok: Partner.") + logger.info("Trade Ok: Partner.") elif packet.is_type(SMSG_TRADE_CANCEL): trader_state.reset() - logging.info("Trade Cancel.") + logger.info("Trade Cancel.") elif packet.is_type(SMSG_TRADE_COMPLETE): commitMessage="" @@ -1062,18 +1070,18 @@ def main(): tradey.saveData(commitMessage) trader_state.reset() - logging.info("Trade Complete.") + logger.info("Trade Complete.") errorOccured = player_node.check_inventory(user_tree, sale_tree) if errorOccured: - logging.info(errorOccured) + logger.info(errorOccured) shop_broadcaster.stop() exit(0) else: pass # On Disconnect/Exit - logging.info("Server disconnect.") + logger.info("Server disconnect.") shop_broadcaster.stop() mapserv.close() -- cgit v1.2.3-70-g09d2 From fa18bcbed1a8099c1789443c2bcfbe747edf7745 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 1 Apr 2012 00:03:04 +0100 Subject: Update items.xml --- data_template/items.xml | 286 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 260 insertions(+), 26 deletions(-) diff --git a/data_template/items.xml b/data_template/items.xml index dcef0ab..3a3354f 100644 --- a/data_template/items.xml +++ b/data_template/items.xml @@ -66,6 +66,9 @@ hairstyles/hairstyle18.xml + + hairstyles/hairstyle19.xml + @@ -88,7 +91,7 @@ weapon-bow.xml - weapons/bows/bow_shoot_1.ogg + @@ -343,7 +346,7 @@ weight="600" missile-particle="graphics/particles/arrow.particle.xml"> weapon-bow.xml - weapons/bows/bow_shoot_1.ogg + weapon-bow.xml - weapons/bows/bow_shoot_1.ogg + + equipment/chest/valentine-dress.xml|#bf0e08 equipment/chest/valentine-dress.xml|#bf0e08 @@ -2795,9 +2799,205 @@ description="The orifice secretions of a grub." type="generic" weight="2"/> - - + + + + + + + + + + + + equipment/head/earmuffs.xml + + + + + + + + equipment/head/elf-nightcap.xml + + + equipment/head/sunglasses.xml + + + equipment/head/knit-cap.xml + + + equipment/legs/pants-male.xml|#2a2117,2f2112,493219,61411e,724c22,a97e4f + equipment/legs/pants-female.xml|#2a2117,2f2112,493219,61411e,724c22,a97e4f + + + + + + + + + + weapon-bow.xml - weapons/bows/bow_shoot_1.ogg + @@ -3514,6 +3714,7 @@ description="A thin, soft and warm black sweater." effect="M. Attack -16" type="equip-torso" + defense="8" weight="35"> equipment/chest/vnecksweater-male.xml|#111111,222222,333333,444444,555555,aaaaaa equipment/chest/vnecksweater-female.xml|#111111,222222,333333,444444,555555,aaaaaa @@ -4931,7 +5132,7 @@ equipment/head/wizard-hat.xml equipment/head/monocle.xml + + equipment/head/panhat.xml + + + equipment/head/chefhat.xml + + + -- cgit v1.2.3-70-g09d2 From f74ec66b339cb81bf4bc6e3e59935137ae7b63ce Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 1 Apr 2012 23:15:40 +0100 Subject: Fix: Use sys.exit() so the status can be passed to a sh script (for restarting). --- main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 4f39b1b..d0297eb 100755 --- a/main.py +++ b/main.py @@ -34,7 +34,7 @@ try: import config except: print "no config file found. please move config.py.template to config.py and edit to your needs!" - exit(0); + sys.exit(0); from being import * from net.packet import * @@ -898,7 +898,7 @@ def main(): if errorOccured: logger.info(errorOccured) shop_broadcaster.stop() - exit(0) + sys.exit(1) else: logger.info("Inventory Check Passed.") @@ -1076,7 +1076,7 @@ def main(): if errorOccured: logger.info(errorOccured) shop_broadcaster.stop() - exit(0) + sys.exit(1) else: pass -- cgit v1.2.3-70-g09d2 From 69b1e74409bcb227559162f3f0fdcc46a84adb44 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Sun, 1 Apr 2012 23:57:39 +0100 Subject: Add a shell script to manage reboot. --- start.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 start.sh diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..830eece --- /dev/null +++ b/start.sh @@ -0,0 +1,18 @@ +#!/bin/bash +MM_ACTIVE=1 + +while [ $MM_ACTIVE != 0 ] +do + echo "Starting tradey...." + python2.7 main.py >> error_log.txt + + if [ "$?" != "0" ]; then + # Inventory/Money out of sync + echo "tradey quit with error at:" + date + MM_ACTIVE=0 + else + echo "Tradey quit normally, sleeping 60 seconds before a restart" + sleep 60 + fi +done -- cgit v1.2.3-70-g09d2 From 8754b59461477ccb1f93c215a2b49935306d13b0 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Thu, 5 Apr 2012 18:58:32 +0100 Subject: Add - A simple list for items which MM won't sell. --- config.py.template | 1 + main.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/config.py.template b/config.py.template index 2d3155e..8cad23e 100644 --- a/config.py.template +++ b/config.py.template @@ -6,3 +6,4 @@ password = "" relist_time = 604800 # Time in seconds before an item needs to be relisted. character = 0 #slot character is in, 0 for first, 1 for second, 2 for third admin = "Admin " +nosell = [833, 3000, 727] # Items which can't be sold - just add the itemid to the list. diff --git a/main.py b/main.py index d0297eb..6978401 100755 --- a/main.py +++ b/main.py @@ -444,6 +444,9 @@ def process_whisper(nick, msg, mapserv): if item_id == -10: mapserv.sendall(whisper(nick, "Item not found, check spelling.")) return + elif item_id in config.nosell: + mapserv.sendall(whisper(nick, "That item can't be added to ManaMarket, as its too heavy.")) + return if amount > 1 and ItemDB.getItem(item_id).type != 'equip-ammo' and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equipment per slot.")) -- cgit v1.2.3-70-g09d2 From 5079421781f84f353676d9caa95edec7c799e883 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Mon, 9 Apr 2012 17:50:48 +0100 Subject: Add: record the time of !add and !relist To make it possible to do a purge of users in a few months. --- main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.py b/main.py index 6978401..1654b3d 100755 --- a/main.py +++ b/main.py @@ -577,6 +577,8 @@ def process_whisper(nick, msg, mapserv): sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) sale_tree.save() mapserv.sendall(whisper(nick, "The item has been successfully relisted.")) + user_tree.get_user(nick).set('last_use', str(time.time())) + user_tree.save() else: mapserv.sendall(whisper(nick, "This item can no longer be relisted. Please collect it using !getback "+str(uid)+".")) return @@ -1045,6 +1047,7 @@ def main(): sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) user_tree.get_user(trader_state.item.player).set('used_stalls', \ str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) + user_tree.get_user(trader_state.item.player).set('last_use', str(time.time())) commitMessage = "Add" elif trader_state.item.get == 0: # !buy \ !getback -- cgit v1.2.3-70-g09d2 From aef0bcdbda77b07f6f99e629e0499d7e576b6741 Mon Sep 17 00:00:00 2001 From: Dipesh Amin Date: Wed, 11 Apr 2012 12:56:52 +0100 Subject: Don't initiate trades, if the weight limit will be reached. --- main.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main.py b/main.py index 1654b3d..b13c354 100755 --- a/main.py +++ b/main.py @@ -441,12 +441,18 @@ def process_whisper(nick, msg, mapserv): price = int(broken_string[2]) item_name = " ".join(broken_string[3:]) item_id = ItemDB.findId(item_name) + + weight = ItemDB.item_names[item_id].weight*amount + if item_id == -10: mapserv.sendall(whisper(nick, "Item not found, check spelling.")) return elif item_id in config.nosell: mapserv.sendall(whisper(nick, "That item can't be added to ManaMarket, as its too heavy.")) return + elif weight + player_node.WEIGHT > player_node.MaxWEIGHT: + mapserv.sendall(whisper(nick, "I've not got enough room left to carry those. Please try again later. ")) + return if amount > 1 and ItemDB.getItem(item_id).type != 'equip-ammo' and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equipment per slot.")) -- cgit v1.2.3-70-g09d2 From a93b2573b8b04cf883dff0c75efa3f0630e3e79e Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Fri, 26 Sep 2014 18:56:16 +0200 Subject: Added changes done outside of git Those changes have been done on the server directly without continueing the git history (or at least since the history i know). --- README | 3 +- being.py | 24 +----- config.py.template | 7 +- find-unused-accounts.pl | 28 +++++++ main.py | 15 +++- net/packet.py | 2 +- net/packet_out.py | 24 ------ net/protocol.py | 24 ------ player.py | 26 ++----- stats/process_salelog/Readme | 1 + stats/process_salelog/main.py | 59 +++++++++++++++ stats/process_salelog/main_stat.py | 151 +++++++++++++++++++++++++++++++++++++ stats/process_salelog/utils.py | 82 ++++++++++++++++++++ stats/update_sales.sh | 5 ++ tradey.py | 24 +----- utils.py | 27 ++----- 16 files changed, 364 insertions(+), 138 deletions(-) create mode 100755 find-unused-accounts.pl create mode 100644 stats/process_salelog/Readme create mode 100755 stats/process_salelog/main.py create mode 100755 stats/process_salelog/main_stat.py create mode 100644 stats/process_salelog/utils.py create mode 100755 stats/update_sales.sh diff --git a/README b/README index bfdb8f7..461b6d5 100644 --- a/README +++ b/README @@ -1,6 +1,5 @@ - To get your own copy of tradey: cp config.py.template config.py -cp data_template data/ +cp item.xml data/ cd data git init diff --git a/being.py b/being.py index 3c920f6..3c70616 100644 --- a/being.py +++ b/being.py @@ -1,26 +1,10 @@ #!/usr/bin/python """ -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org """ def job_type(job): diff --git a/config.py.template b/config.py.template index 8cad23e..e55b2f6 100644 --- a/config.py.template +++ b/config.py.template @@ -1,9 +1,8 @@ -#server = "server.themanaworld.org" -server = "caliban.homeip.net" +server = "server.themanaworld.org" port = 6901 account = "" password = "" relist_time = 604800 # Time in seconds before an item needs to be relisted. character = 0 #slot character is in, 0 for first, 1 for second, 2 for third -admin = "Admin " -nosell = [833, 3000, 727] # Items which can't be sold - just add the itemid to the list. +admin = "" +#nosell = [] # Items which can't be sold - just add the itemid to the list. diff --git a/find-unused-accounts.pl b/find-unused-accounts.pl new file mode 100755 index 0000000..9667f5a --- /dev/null +++ b/find-unused-accounts.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl +use XML::Simple; +use warnings; +use strict; +use Data::Dumper; + +my $xml = XML::Simple->new(); +my $users = $xml->XMLin("data/user.xml", KeyAttr => {}); +my %l; + +# Snarf through the XML data. Build a hash: +# username => lastuse +# Only for users with no items and no money. +# For some reason last_use is floating point so let's fix that. +foreach my $user (@{$users->{user}}) { + if ($user->{'used_stalls'} == 0 && $user->{'money'} == 0) { + $user->{'last_use'} = 0 unless ($user->{'last_use'}); + $l{ $user->{'name'} } = int($user->{'last_use'}); + } +} + + +print("Last used\t\t\tUsername\n"); +foreach ( sort { $l{$a} cmp $l{$b} || $a cmp $b } keys %l ) { + print gmtime($l{$_}) . "\t$_\n"; +} + + diff --git a/main.py b/main.py index b13c354..eda5f64 100755 --- a/main.py +++ b/main.py @@ -68,6 +68,9 @@ def process_whisper(nick, msg, mapserv): user = user_tree.get_user(nick) broken_string = msg.split() + if len(broken_string) == 0: + return + if user != -10: if int(user.get("accesslevel")) == -1: # A user who has been blocked for abuse. if int(user.get("used_stalls")) == 0 and int(user.get("money")) == 0: @@ -453,6 +456,9 @@ def process_whisper(nick, msg, mapserv): elif weight + player_node.WEIGHT > player_node.MaxWEIGHT: mapserv.sendall(whisper(nick, "I've not got enough room left to carry those. Please try again later. ")) return + elif ItemDB.item_names[item_id].weight > 10 and amount > 150: + mapserv.sendall(whisper(nick, "Sorry, as each of those items weighs more than 10g you can only add a maximum quantity of 150.")) + return if amount > 1 and ItemDB.getItem(item_id).type != 'equip-ammo' and 'equip' in ItemDB.getItem(item_id).type: mapserv.sendall(whisper(nick, "You can only add one piece of equipment per slot.")) @@ -766,6 +772,7 @@ def main(): shop_broadcaster.mapserv = mapserv # Map server packet loop + print "Entering map packet loop\n"; while True: data = mapserv.recv(2048) if not data: @@ -997,9 +1004,15 @@ def main(): logger.info("Trade item add response: Successfully added item.") if trader_state.item: if trader_state.item.get == 0 and index != 0-inventory_offset: # Make sure the correct item is given! + # index & amount are Always 0 if player_node.inventory[index].itemId != trader_state.item.id or \ amount != trader_state.item.amount: - mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + logger.info("Index: %s" % index) + logger.info("P.ItemId: %s" % player_node.inventory[index].itemId) + logger.info("T.ItemId: %s" % trader_state.item.id) + logger.info("P.Amount: %s" % amount) + logger.info("T.Amount: %s" % trader_state.item.amount) + #mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) # If Trade item add successful - Remove the item from the inventory state. if index != 0-inventory_offset: # If it's not money diff --git a/net/packet.py b/net/packet.py index 52bdf71..16b4f79 100644 --- a/net/packet.py +++ b/net/packet.py @@ -1,5 +1,5 @@ -# The PacketBuffer class has been adapted from source originally released by gnufrk +"""The PacketBuffer class has been adapted from source originally released by gnufrk""" import struct diff --git a/net/packet_out.py b/net/packet_out.py index 79f9917..1d6e2d2 100644 --- a/net/packet_out.py +++ b/net/packet_out.py @@ -1,27 +1,3 @@ -""" -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller - -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. -""" - from packet import * from protocol import * diff --git a/net/protocol.py b/net/protocol.py index 8b97542..4a4b74f 100644 --- a/net/protocol.py +++ b/net/protocol.py @@ -1,27 +1,3 @@ -""" -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller - -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. -""" - SMSG_LOGIN_DATA = 0x0069 SMSG_CHAR_LOGIN = 0x006b SMSG_CHAR_MAP_INFO = 0x0071 diff --git a/player.py b/player.py index 6417368..ed80f66 100644 --- a/player.py +++ b/player.py @@ -1,26 +1,10 @@ #!/usr/bin/python """ -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org """ import copy @@ -78,7 +62,7 @@ class Player: total_money += int(user.get('money')) if total_money != self.MONEY: - return "Server and client money out of sync." + return "Server and client money out of sync. Market: %s Player %s" % (total_money, self.MONEY) return 0 diff --git a/stats/process_salelog/Readme b/stats/process_salelog/Readme new file mode 100644 index 0000000..6b80ea7 --- /dev/null +++ b/stats/process_salelog/Readme @@ -0,0 +1 @@ +Usage: python main.py sales.log diff --git a/stats/process_salelog/main.py b/stats/process_salelog/main.py new file mode 100755 index 0000000..4ad2dd3 --- /dev/null +++ b/stats/process_salelog/main.py @@ -0,0 +1,59 @@ +#!/usr/bin/python +""" + + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + tradey, a package, which implements an Automated Market Bot for "The Mana World" a 2D MMORPG. + +""" + +import logging +import socket +import sys +import time +import string +import utils +import locale + +ItemDB = utils.ItemDB() + +def main(): + in_file = sys.argv[1] + out_file = sys.argv[2] + locale.setlocale(locale.LC_ALL, '') + + out_obj = open(out_file, 'w') + in_obj = open(in_file, 'r') + + out_obj.write(' \n') + out_obj.write(' \n') + out_obj.write(' \n') + out_obj.write('ManaMarket Sales \n') + out_obj.write('

ManaMarket Sales

') + out_obj.write(' \n') + out_obj.write('\n') + + sales = in_obj.readlines() + + sale_total = 0 + items_sold = 0 + for line in sales: + line = line.split() + t_time = time.gmtime(float(line[3])) + unit_price = int(line[2])/int(line[1]) + out_obj.write('\n') + sale_total += int(line[2]) + items_sold += int(line[1]) + + out_obj.write('
Item Name Amount Price Time
'+ItemDB.getItem(int(line[0])).name+' '+locale.format("%d", int(line[1]), grouping=True)+' '+locale.format("%d", unit_price, grouping=True)+' '+time.asctime(t_time)+'
\n') + out_obj.write('
Total sales: '+str(sale_total)+' GP
') + out_obj.write('Total number of items sold: '+str(items_sold)+'
') + out_obj.write('Updated: '+time.asctime(time.gmtime())) + out_obj.write(' \n') + in_obj.close() + out_obj.close() + + +if __name__ == '__main__': + main() diff --git a/stats/process_salelog/main_stat.py b/stats/process_salelog/main_stat.py new file mode 100755 index 0000000..9ff71d5 --- /dev/null +++ b/stats/process_salelog/main_stat.py @@ -0,0 +1,151 @@ +#!/usr/bin/python +""" + + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + tradey, a package, which implements an Automated Market Bot for "The Mana World" a 2D MMORPG. + +""" + +import logging +import socket +import sys +import time +import string +import utils +import locale + +class SaleStat: + pass + +ItemDB = utils.ItemDB() + +def main(): + in_file = sys.argv[1] + out_file = sys.argv[2] + locale.setlocale(locale.LC_ALL, '') + + out_obj = open(out_file, 'w') + in_obj = open(in_file, 'r') + + out_obj.write(' \n \ + \n \ + ManaMarket Statistics \n \ + \n \ + \n \ + \n \ +

ManaMarket Statistics

\n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n \ + \n ') + + sales = in_obj.readlines() + + sale_dict = {} + + # Put sales date into a dict. + sale_total = 0 + for line in sales: + line = line.split() + item_id = int(line[0]) + name = ItemDB.getItem(int(line[0])).name + amount = int(line[1]) + price = int(line[2]) + t_time = float(line[3]) + sale_total += int(line[2]) + + if item_id not in sale_dict: + sale_dict[item_id] = [] + + sale_dict[item_id].append([amount, price, t_time]) + + str_list = [] + # calculate the stats + for item in sale_dict: + average_week = 0 + average_week_amount = 0 + average_month = 0 + average_month_amount = 0 + average_all_time = 0 + average_all_time_amount = 0 + min_price = 0 + max_price = 0 + last_sold = 0 + + for n in range(len(sale_dict[item])): + + #out_obj.write('') + + if min_price > sale_dict[item][n][1]/sale_dict[item][n][0] or min_price == 0: + min_price = sale_dict[item][n][1]/sale_dict[item][n][0] + + if max_price < sale_dict[item][n][1]/sale_dict[item][n][0] or max_price == 0: + max_price = sale_dict[item][n][1]/sale_dict[item][n][0] + + if last_sold < sale_dict[item][n][2] or last_sold == 0: + last_sold = sale_dict[item][n][2] + + if (time.time()-sale_dict[item][n][2]) < 7*24*60*60: + average_week_amount += sale_dict[item][n][0] + average_week += sale_dict[item][n][1] + + if (time.time()-sale_dict[item][n][2]) < 30*24*60*60: + average_month_amount += sale_dict[item][n][0] + average_month += sale_dict[item][n][1] + + + average_all_time_amount += sale_dict[item][n][0] + average_all_time += sale_dict[item][n][1] + + average_all_time /= average_all_time_amount + if average_week_amount > 0: + average_week /= average_week_amount + if average_month_amount > 0: + average_month /= average_month_amount + + str_list.append([average_all_time_amount,''+''+ \ + ''+''+''+ ''+''+'']) + + while len(str_list) > 0: + pos = 0 + max_amount = 0 + for m in range(len(str_list)): + if max_amount < str_list[m][0] or max_amount == 0: + max_amount = str_list[m][0] + pos = m + out_obj.write('') + out_obj.write(str_list[pos][1]) + str_list.pop(pos) + + + out_obj.write(' \n') + + out_obj.write('
Item Name Total Amount SoldPriceLast Sold
MinMaxAverage (Week)Average (Month)Average (Overall)
'+ItemDB.getItem(item).name+''+locale.format("%d", average_all_time_amount, grouping=True)+''+ locale.format("%d", min_price, grouping=True) +''+ locale.format("%d", max_price, grouping=True) +''+ \ + locale.format("%d", average_week, grouping=True) +''+ locale.format("%d", average_month, grouping=True) + \ + ''+ locale.format("%d", average_all_time, grouping=True)+''+ time.asctime(time.gmtime(last_sold)) +'
\n') + out_obj.write('
Total sales: '+str(sale_total)+' GP
') + out_obj.write('Updated: '+time.asctime(time.gmtime())+'
') + out_obj.write('For a detailed page showing all sales '+'click here') + + out_obj.write(' \n') + in_obj.close() + out_obj.close() + + +if __name__ == '__main__': + main() diff --git a/stats/process_salelog/utils.py b/stats/process_salelog/utils.py new file mode 100644 index 0000000..fd4e432 --- /dev/null +++ b/stats/process_salelog/utils.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +""" + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller + + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org +""" +from xml.etree.ElementTree import ElementTree +import time + +class Item: + pass + +# Process a recieved ip address. +def parse_ip(a): + return "%s.%s.%s.%s" % ((a % 256),((a >> 8) % 256),((a >> 16) % 256),((a >> 24) % 256)) + +# Remove colors from a message +def remove_colors(msg): + if len(msg) > 2: + for f in range(len(msg)-2): + while (len(msg) > f + 2) and (msg[f] == "#")\ + and (msg[f+1] == "#"): + msg = msg[0:f]+msg[f+3:] + return msg + +# Encode string - used with 4144 shop compatibility. +def encode_str(value, size): + output = '' + base = 94 + start = 33 + while value: + output += chr(value % base + start) + value /= base + + while len(output) < size: + output += chr(start) + + return output + +class ItemDB: + """ + A simple class to look up information from the items.xml file. + """ + def __init__(self): + print "Loading ItemDB" + self.item_names = {} + self.itemdb_file = ElementTree(file="../data/items.xml") + + for item in self.itemdb_file.getroot(): + if item.get('id') > 500: + item_struct = Item() + item_struct.name = item.get('name') + if item.get('weight'): + item_struct.weight = item.get('weight') + if item.get('type'): + item_struct.type = item.get('type') + item_struct.description = item.get('description') + self.item_names[int(item.get('id'))] = item_struct + + def getItem(self, item_id): + return self.item_names[item_id] + + def findId(self, name): + for item_id in self.item_names: + if self.item_names[item_id].name == name: + return item_id + return -10 #Not found + +class ItemLog: + """ Writes all sales to a log file, for later processing.""" + def __init__(self): + self.log_file = 'data/logs/sale.log' + + def add_item(self, item_id, amount, price): + file_node = open(self.log_file, 'a') + file_node.write(str(item_id)+" "+str(amount)+" "+str(price)+" "+str(time.time())+"\n") + file_node.close() + +if __name__ == '__main__': + print "Do not run this file directly. Run main.py" diff --git a/stats/update_sales.sh b/stats/update_sales.sh new file mode 100755 index 0000000..62a4e1e --- /dev/null +++ b/stats/update_sales.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd /home/tmwserver/ManaMarket/stats +python /home/tmwserver/ManaMarket/stats/process_salelog/main.py /home/tmwserver/ManaMarket/data/logs/sale.log /var/www/tmw-homepage/server/manamarket.html +python /home/tmwserver/ManaMarket/stats/process_salelog/main_stat.py /home/tmwserver/ManaMarket/data/logs/sale.log /var/www/tmw-homepage/server/manamarket_stats.html +chmod 644 /var/www/tmw-homepage/server/manamarket.html /var/www/tmw-homepage/server/manamarket_stats.html diff --git a/tradey.py b/tradey.py index 673fc46..01f855e 100644 --- a/tradey.py +++ b/tradey.py @@ -1,26 +1,10 @@ #!/usr/bin/python """ -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org """ import time import os diff --git a/utils.py b/utils.py index f911d43..07c4451 100644 --- a/utils.py +++ b/utils.py @@ -1,26 +1,10 @@ #!/usr/bin/python """ -Copyright 2011, Dipesh Amin -Copyright 2011, Stefan Beller + Copyright 2011, Dipesh Amin + Copyright 2011, Stefan Beller -This file is part of tradey, a trading bot in The Mana World -see www.themanaworld.org - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Additionally to the GPL, you are *strongly* encouraged to share any modifications -you do on these sources. + This file is part of tradey, a trading bot in the mana world + see www.themanaworld.org """ from xml.etree.ElementTree import ElementTree from player import Item @@ -128,9 +112,10 @@ class Broadcast: def send_broadcast(self): while self.Active: - if (time.time() - self.Timer) > 2 * 60: + if (time.time() - self.Timer) > 60: self.mapserv.sendall(emote(193)) self.Timer = time.time() + #print "shop_broadcast" else: time.sleep(0.1) -- cgit v1.2.3-70-g09d2