You can subscribe to this list here.
2009 |
Jan
|
Feb
(9) |
Mar
(11) |
Apr
|
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(9) |
Nov
(5) |
Dec
(18) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
(4) |
Feb
|
Mar
|
Apr
(4) |
May
|
Jun
|
Jul
(11) |
Aug
(33) |
Sep
(33) |
Oct
|
Nov
|
Dec
|
From: <Blu...@us...> - 2010-08-09 17:31:02
|
Revision: 365 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=365&view=rev Author: BlueWolf_ Date: 2010-08-09 17:30:56 +0000 (Mon, 09 Aug 2010) Log Message: ----------- Starting with the GUI button for the login. So far, only the default state has been made Added Paths: ----------- res/images/xcf/login-button.xcf res/images/xcf/login-textbox.xcf Removed Paths: ------------- res/images/xcf/login-gui.xcf Added: res/images/xcf/login-button.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/login-button.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: res/images/xcf/login-gui.xcf =================================================================== (Binary files differ) Copied: res/images/xcf/login-textbox.xcf (from rev 353, res/images/xcf/login-gui.xcf) =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-09 17:28:31
|
Revision: 364 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=364&view=rev Author: BlueWolf_ Date: 2010-08-09 17:28:24 +0000 (Mon, 09 Aug 2010) Log Message: ----------- Fixed the GUI textbox regarding getting focus and getting clicks. The GUI was a bit confused with both of them Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-08 17:38:24 UTC (rev 363) +++ trunk/client/gui.py 2010-08-09 17:28:24 UTC (rev 364) @@ -32,6 +32,9 @@ self.focus = None self.mousedown = None + # Settings + self.can_lose_focus = True + # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -147,13 +150,12 @@ # Tell this object child.focus = True - child.got_focus(0) + child.got_focus() def event(self, ev): """ All the events from pygame should go here """ - if self.frozen: return if ev.type == MOUSEMOTION: # Mouse movement @@ -164,7 +166,7 @@ # the interface pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].got_focus(1, pos) + self.mousedown[1].click(1, pos) return True else: # Check which object we hover @@ -177,28 +179,29 @@ # Check which object we've focused rect, hover = self.this_pos(ev.pos) if hover: - # Change the focus - if self.focus: - self.focus.focus = False - self.focus.lost_focus() - self.focus = None + pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) + hover.click(0, pos) - self.focus = hover - - # Tell this object self.mousedown = (rect, hover) - hover.focus = True - pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) - hover.got_focus(0, pos) + if self.focus != hover: + # Change the focus + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = hover - self.update_mouse() + # Tell this object + hover.focus = True + hover.got_focus() return True else: # Did an object lost focus? - if self.focus: + if self.focus and self.can_lose_focus: self.focus.focus = False self.focus.lost_focus() self.focus = None @@ -207,7 +210,7 @@ # Release mousebutton after we've clicked on an object pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].got_focus(2, pos) + self.mousedown[1].click(2, pos) self.mousedown = None self.update_mouse() @@ -238,6 +241,9 @@ self.give_focus(self.children[pos]) + + + class Object(): def __init__(self, name, rect, main_parent, parent): @@ -364,6 +370,9 @@ self.give_focus(self.children[pos]) + + + class Textbox(Object): def __defaults__(self): @@ -378,15 +387,20 @@ def set_style(self, style): """ + Change the stle for this textbox Possible styles: * login """ if style == "login": + + # Check the requirements if self.rect.height != 37: raise GuiError("Height should be 37") if self.rect.width < 25: raise GuiError("Width should be 25 or bigger ") + # Load the base images. We will generated the actual images right + # now layoutimg = load_image(True, "images", "gui", "text_login.png") self.font = pygame.font.Font(real_path("fonts", \ @@ -395,12 +409,12 @@ # Create backgroundsurf self.backgroundsurf.fill([0,0,0,0]) - # Left + # Left part self.backgroundsurf.blit(layoutimg, (0, 0), (0, 0, 12, 74)) - # Right + # Right part self.backgroundsurf.blit(layoutimg, (self.rect.width-12, 0), \ (15, 0, 12, 74)) - # Middle + # Middle part middle = pygame.Surface((1, 74), SRCALPHA).convert_alpha() middle.blit(layoutimg, (0, 0,), (13, 0, 1, 74)) middle = pygame.transform.scale(middle, (self.rect.width-24, 74)) @@ -414,6 +428,7 @@ def set_type(self, type): """ + Change the type for this textbox Possible types: * text * password @@ -425,6 +440,9 @@ self.update() def render(self): + """ + Render our surface, as requested from the all mighty Container + """ if self.backgroundsurf == None: return self.surf.fill([0,0,0,0]) @@ -467,20 +485,21 @@ pygame.draw.line(self.surf, [118, 58, 19], (pos+cursorpos+6, 10), (pos+cursorpos+6, 26), 2) def hovering(self, value): - print "hover", self.name, value + pass - def got_focus(self, state, pos = None): - print "got_focus", self.name, state, pos - - if state == 0: # We got the focus! + def click(self, state, pos): + if state == 0: # [TODO] Calculate position based on pos + # self.cursorpos = ... - self.update() + if self.focus: + self.update() + + def got_focus(self): + # We got the focus! + self.update() def lost_focus(self): - print "lost_focus", self.name - - self.cursorpos = len(self.input) self.update() def keypress(self, ev): @@ -492,7 +511,7 @@ self.cursorpos = 0 else: - + print pygame.key.name(ev.key) if ev.key == K_LEFT: # Cursorpos change if self.cursorpos > 0: self.cursorpos -= 1 @@ -500,9 +519,10 @@ if self.cursorpos < len(self.input): self.cursorpos += 1 elif ev.key == K_BACKSPACE: # Backspace - self.input = self.input[:self.cursorpos-1] + \ - self.input[self.cursorpos:] - if self.cursorpos > 0: self.cursorpos -= 1 + if self.cursorpos != 0: + self.input = self.input[:self.cursorpos-1] + \ + self.input[self.cursorpos:] + self.cursorpos -= 1 elif ev.key == K_DELETE: # Delete self.input = self.input[:self.cursorpos] + \ Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-08 17:38:24 UTC (rev 363) +++ trunk/client/playground.py 2010-08-09 17:28:24 UTC (rev 364) @@ -99,16 +99,17 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui(self.drawlogingui) + self.logingui = gui(self.logingui_draw) + self.logingui.can_lose_focus = False - username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) + username = self.logingui.add("textbox", "usr", (345, 279, 310, 37)) username.set_style("login") - username.cb_keypress = self.guikeypress + username.cb_keypress = self.logingui_keypress - password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) + password = self.logingui.add("textbox", "pwd", (345, 340, 310, 37)) password.set_style("login") password.set_type("password") - password.cb_keypress = self.guikeypress + password.cb_keypress = self.logingui_keypress #login = gui.Button("login", (0, 100, 417, 50)) self.logingui.give_focus(username) @@ -122,7 +123,7 @@ sh['update']() - def drawlogingui(self, rect): + def logingui_draw(self, rect): print "GUIupdate", rect self.surf.blit(self.loginbg, rect, rect) @@ -131,7 +132,7 @@ sh['update'](rect) - def guikeypress(self, obj, ev): + def logingui_keypress(self, obj, ev): if ev.type == KEYDOWN: if ev.unicode == "\r": if obj.name == "usr": This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-08 17:38:30
|
Revision: 363 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=363&view=rev Author: BlueWolf_ Date: 2010-08-08 17:38:24 +0000 (Sun, 08 Aug 2010) Log Message: ----------- Keys with ctrl pressed won't be seen as characters anymore. Can be used as shortkeys now Modified Paths: -------------- trunk/client/gui.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-08 15:24:53 UTC (rev 362) +++ trunk/client/gui.py 2010-08-08 17:38:24 UTC (rev 363) @@ -485,41 +485,45 @@ def keypress(self, ev): if ev.type == KEYDOWN: - if ev.key == K_LEFT: # Cursorpos change - if self.cursorpos > 0: self.cursorpos -= 1 + if ev.mod & KMOD_CTRL: # Ctrl combination + + if ev.key == K_BACKSPACE: # Remove the whole input + self.input = "" + self.cursorpos = 0 - elif ev.key == K_RIGHT: # Cursorpos change - if self.cursorpos < len(self.input): self.cursorpos += 1 + else: - elif ev.key == K_BACKSPACE: # Backspace - if ev.mod & KMOD_CTRL: - self.input = "" - self.cursorpos = 0 - else: + if ev.key == K_LEFT: # Cursorpos change + if self.cursorpos > 0: self.cursorpos -= 1 + + elif ev.key == K_RIGHT: # Cursorpos change + if self.cursorpos < len(self.input): self.cursorpos += 1 + + elif ev.key == K_BACKSPACE: # Backspace self.input = self.input[:self.cursorpos-1] + \ self.input[self.cursorpos:] if self.cursorpos > 0: self.cursorpos -= 1 - - elif ev.key == K_DELETE: # Delete - self.input = self.input[:self.cursorpos] + \ - self.input[self.cursorpos+1:] - - elif ev.key == K_HOME: # Go to the beginning - self.cursorpos = 0 - - elif ev.key == K_END: # Go to the end - self.cursorpos = len(self.input) - - elif ev.key == K_TAB: # Focus the next object - self.parent.focus_next(self) - - elif ev.unicode == "\r": # Ignore this - pass - elif ev.unicode != "": # Normal text - self.input = self.input[:self.cursorpos] + ev.unicode + \ - self.input[self.cursorpos:] - self.cursorpos += 1 + + elif ev.key == K_DELETE: # Delete + self.input = self.input[:self.cursorpos] + \ + self.input[self.cursorpos+1:] + elif ev.key == K_HOME: # Go to the beginning + self.cursorpos = 0 + + elif ev.key == K_END: # Go to the end + self.cursorpos = len(self.input) + + elif ev.key == K_TAB: # Focus the next object + self.parent.focus_next(self) + + elif ev.unicode == "\r": # Ignore this + pass + elif ev.unicode != "": # Normal text + self.input = self.input[:self.cursorpos] + ev.unicode + \ + self.input[self.cursorpos:] + self.cursorpos += 1 + self.update() if self.cb_keypress: self.cb_keypress(self, ev) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-08 15:24:59
|
Revision: 362 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=362&view=rev Author: BlueWolf_ Date: 2010-08-08 15:24:53 +0000 (Sun, 08 Aug 2010) Log Message: ----------- Textbox now with working cursor! Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-07 21:37:36 UTC (rev 361) +++ trunk/client/gui.py 2010-08-08 15:24:53 UTC (rev 362) @@ -55,7 +55,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update, self.update_mouse) + obj = Obj(name, rect, self, self) self.children.append(obj) return obj @@ -130,6 +130,25 @@ self.hover.hovering(False) self.hover = None + def give_focus(self, *obj): + if type(obj[0]) == str: + child = self + for part in obj: + child = child[part] + else: + child = obj[0] + + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = child + + # Tell this object + child.focus = True + child.got_focus(0) + def event(self, ev): """ All the events from pygame should go here @@ -145,7 +164,7 @@ # the interface pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].click(1, pos) + self.mousedown[1].got_focus(1, pos) return True else: # Check which object we hover @@ -171,7 +190,7 @@ hover.focus = True pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) - hover.click(0, pos) + hover.got_focus(0, pos) self.update_mouse() @@ -188,7 +207,7 @@ # Release mousebutton after we've clicked on an object pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].click(2, pos) + self.mousedown[1].got_focus(2, pos) self.mousedown = None self.update_mouse() @@ -211,15 +230,21 @@ return rect, hover return None, None + + def focus_next(self, current): + pos = self.children.index(current) + 1 + if pos == len(self.children): pos = 0 + + self.give_focus(self.children[pos]) class Object(): - def __init__(self, name, rect, update, update_mouse): + def __init__(self, name, rect, main_parent, parent): self.name = name self.rect = Rect(rect) - self.parent_update = update - self.update_mouse = update_mouse + self.main_parent = main_parent + self.parent = parent self.needs_update = False self.frozen = True # Don't update until everything has been # loaded @@ -228,6 +253,9 @@ self.hover = False self.focus = False + # Callbacks + self.cb_keypress = None + # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -254,7 +282,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update, self.update_mouse) + obj = Obj(name, rect, self.main_parent, self) self.children.append(obj) return obj @@ -278,7 +306,7 @@ # We need to calculate our relative position rect.move_ip(self.rect.left, self.rect.top) - self.parent_update(rect) + self.parent.update(rect) def blit(self, rect, surf, onto): """ @@ -309,13 +337,12 @@ child.unfreeze(False) if isparent: - self.update_mouse() + self.main_parent.update_mouse() self.frozen = False self.update(self.rect) else: self.frozen = False - - + def this_pos(self, pos): # Return the object on this position @@ -329,6 +356,12 @@ return rect, hover return self.rect.move(0,0), self + + def focus_next(self, current): + pos = self.children.index(current) + 1 + if pos == len(self.children): pos = 0 + + self.give_focus(self.children[pos]) class Textbox(Object): @@ -406,6 +439,8 @@ self.surf.blit(self.backgroundsurf, (0,0), \ (0, top, self.rect.width, 37)) + truewidth = self.rect.width - 12 # Width without the borders + # Blit the text inp = self.input if self.type == "password": @@ -413,13 +448,29 @@ color = [(141, 56, 0), (189, 84, 15)][self.focus] text = self.font.render(inp, True, color) - self.surf.blit(text, (10, 10)) + textwidth = text.get_width() + + cursorpos = self.font.size(inp[:self.cursorpos])[0] + if textwidth < truewidth: # Text is smaller than the input + pos = (truewidth/2) - (textwidth/2) + elif cursorpos < (truewidth/2): # Cursor is on the left + pos = 0 + elif textwidth-cursorpos < (truewidth/2): # Cursor is on the right + pos = -textwidth + truewidth - 2 + else: # Cursor is in the center + pos = -cursorpos + (truewidth/2) + + self.surf.blit(text, (6, 10), (-pos, 0, truewidth, 17)) + + # Blit cursor + if self.focus: + pygame.draw.line(self.surf, [118, 58, 19], (pos+cursorpos+6, 10), (pos+cursorpos+6, 26), 2) def hovering(self, value): print "hover", self.name, value - def click(self, state, pos): - print "click", self.name, state, pos + def got_focus(self, state, pos = None): + print "got_focus", self.name, state, pos if state == 0: # We got the focus! # [TODO] Calculate position based on pos @@ -452,14 +503,26 @@ elif ev.key == K_DELETE: # Delete self.input = self.input[:self.cursorpos] + \ self.input[self.cursorpos+1:] - + + elif ev.key == K_HOME: # Go to the beginning + self.cursorpos = 0 + + elif ev.key == K_END: # Go to the end + self.cursorpos = len(self.input) + + elif ev.key == K_TAB: # Focus the next object + self.parent.focus_next(self) + + elif ev.unicode == "\r": # Ignore this + pass elif ev.unicode != "": # Normal text - self.input = self.input[:self.cursorpos] + ev.unicode + \ self.input[self.cursorpos:] self.cursorpos += 1 self.update() + + if self.cb_keypress: self.cb_keypress(self, ev) class GuiError(Exception): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-07 21:37:36 UTC (rev 361) +++ trunk/client/playground.py 2010-08-08 15:24:53 UTC (rev 362) @@ -38,7 +38,7 @@ if self.status == "login": # Some temporary debug stuff - if ev.type == KEYDOWN and ev.unicode == "\r": + if ev.type == KEYDOWN and ev.key == K_F2: # Fake login self.drawlogin("logging in") sh['client'].login("test123", sha1("test123").hexdigest()) @@ -103,13 +103,15 @@ username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) username.set_style("login") + username.cb_keypress = self.guikeypress password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) password.set_style("login") password.set_type("password") + password.cb_keypress = self.guikeypress #login = gui.Button("login", (0, 100, 417, 50)) - + self.logingui.give_focus(username) self.logingui.unfreeze() @@ -128,3 +130,9 @@ self.surf.blit(self.logingui.surf, rect, rect) sh['update'](rect) + + def guikeypress(self, obj, ev): + if ev.type == KEYDOWN: + if ev.unicode == "\r": + if obj.name == "usr": + self.logingui.give_focus("pwd") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 21:37:42
|
Revision: 361 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=361&view=rev Author: BlueWolf_ Date: 2010-08-07 21:37:36 +0000 (Sat, 07 Aug 2010) Log Message: ----------- Added more interaction with the GUI. You can now type something into the textboxes. I also moved the fake-registration button to F1, in case one still needs it Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-07 20:18:26 UTC (rev 360) +++ trunk/client/gui.py 2010-08-07 21:37:36 UTC (rev 361) @@ -30,6 +30,7 @@ self.children = [] self.hover = None self.focus = None + self.mousedown = None # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ @@ -103,31 +104,32 @@ if sh['has_hover']: # Get the current hovered object - hover = self.this_pos(pos) + rect, hover = self.this_pos(pos) # Is it different from the previous check? if hover != self.hover: # De-hover the previous one if self.hover: self.hover.hover = False - self.hover.update() + self.hover.hovering(False) self.hover = hover # Hover the current one if self.hover: self.hover.hover = True - self.hover.update() + self.hover.hovering(True) + + if hover: return True # Disable events further down the interface + else: # Remove the previous hover if self.hover: self.hover.hover = False - self.hover.update() + self.hover.hovering(False) self.hover = None - - def event(self, ev): """ All the events from pygame should go here @@ -136,23 +138,79 @@ if self.frozen: return if ev.type == MOUSEMOTION: # Mouse movement - self.update_mouse(ev.pos) + + # When the mousebutton is pressed on a object + if self.mousedown: + # Tell this object and stop processing this event further down + # the interface + pos = (ev.pos[0] - self.mousedown[0][0], \ + ev.pos[1] - self.mousedown[0][1]) + self.mousedown[1].click(1, pos) + return True + else: + # Check which object we hover + return self.update_mouse(ev.pos) elif ev.type == ACTIVEEVENT and ev.state == 1: # Mouse focus self.update_mouse() + + elif ev.type == MOUSEBUTTONDOWN: # Clicking + # Check which object we've focused + rect, hover = self.this_pos(ev.pos) + if hover: + # Change the focus + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = hover + + # Tell this object + self.mousedown = (rect, hover) + + hover.focus = True + pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) + hover.click(0, pos) + + self.update_mouse() + + return True + else: + # Did an object lost focus? + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + elif ev.type == MOUSEBUTTONUP and self.mousedown: # Clicking + # Release mousebutton after we've clicked on an object + pos = (ev.pos[0] - self.mousedown[0][0], \ + ev.pos[1] - self.mousedown[0][1]) + self.mousedown[1].click(2, pos) + self.mousedown = None + + self.update_mouse() + + return True + + elif (ev.type == KEYDOWN or ev.type == KEYUP) and self.focus: + self.focus.keypress(ev) + def this_pos(self, pos): - # Return the object on this position + # Return the object and their actual rect on this position for child in self.children: if not child.rect.collidepoint(pos): continue child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) - hover = child.this_pos(child_pos) - if hover: return hover + rect, hover = child.this_pos(child_pos) + if hover: + return rect, hover - return None + return None, None class Object(): @@ -266,9 +324,11 @@ child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) - return child.this_pos(child_pos) + rect, hover = child.this_pos(child_pos) + rect.move_ip(child.rect[0], child.rect[1]) + return rect, hover - return self + return self.rect.move(0,0), self class Textbox(Object): @@ -279,6 +339,7 @@ self.style = None self.type = "text" + self.font = None self.backgroundsurf = pygame.Surface((self.rect.width, \ self.rect.height*2), SRCALPHA).convert_alpha() @@ -295,6 +356,9 @@ layoutimg = load_image(True, "images", "gui", "text_login.png") + self.font = pygame.font.Font(real_path("fonts", \ + "DejaVuSans-Bold.ttf"), 14) + # Create backgroundsurf self.backgroundsurf.fill([0,0,0,0]) @@ -334,13 +398,68 @@ if self.style == "login": # Which state do we need? - if self.hover: + if self.focus: top = 37 else: top = 0 self.surf.blit(self.backgroundsurf, (0,0), \ (0, top, self.rect.width, 37)) + + # Blit the text + inp = self.input + if self.type == "password": + inp = "*"*len(self.input) + + color = [(141, 56, 0), (189, 84, 15)][self.focus] + text = self.font.render(inp, True, color) + self.surf.blit(text, (10, 10)) + + def hovering(self, value): + print "hover", self.name, value + + def click(self, state, pos): + print "click", self.name, state, pos + + if state == 0: # We got the focus! + # [TODO] Calculate position based on pos + + self.update() + + def lost_focus(self): + print "lost_focus", self.name + + self.cursorpos = len(self.input) + self.update() + + def keypress(self, ev): + if ev.type == KEYDOWN: + if ev.key == K_LEFT: # Cursorpos change + if self.cursorpos > 0: self.cursorpos -= 1 + + elif ev.key == K_RIGHT: # Cursorpos change + if self.cursorpos < len(self.input): self.cursorpos += 1 + + elif ev.key == K_BACKSPACE: # Backspace + if ev.mod & KMOD_CTRL: + self.input = "" + self.cursorpos = 0 + else: + self.input = self.input[:self.cursorpos-1] + \ + self.input[self.cursorpos:] + if self.cursorpos > 0: self.cursorpos -= 1 + + elif ev.key == K_DELETE: # Delete + self.input = self.input[:self.cursorpos] + \ + self.input[self.cursorpos+1:] + + elif ev.unicode != "": # Normal text + + self.input = self.input[:self.cursorpos] + ev.unicode + \ + self.input[self.cursorpos:] + self.cursorpos += 1 + + self.update() class GuiError(Exception): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-07 20:18:26 UTC (rev 360) +++ trunk/client/playground.py 2010-08-07 21:37:36 UTC (rev 361) @@ -43,7 +43,7 @@ self.drawlogin("logging in") sh['client'].login("test123", sha1("test123").hexdigest()) - elif ev.type == KEYDOWN and ev.unicode == "r": + elif ev.type == KEYDOWN and ev.key == K_F1: # Fake signup sh['client'].signup("test123", sha1("test123").hexdigest(), { @@ -52,7 +52,7 @@ }) if self.logingui != None: - self.logingui.event(ev) + return self.logingui.event(ev) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 20:18:32
|
Revision: 360 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=360&view=rev Author: BlueWolf_ Date: 2010-08-07 20:18:26 +0000 (Sat, 07 Aug 2010) Log Message: ----------- Added executable prop to VPS Property Changed: ---------------- trunk/server/VPS.py Property changes on: trunk/server/VPS.py ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 20:14:49
|
Revision: 359 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=359&view=rev Author: BlueWolf_ Date: 2010-08-07 20:14:43 +0000 (Sat, 07 Aug 2010) Log Message: ----------- Added svn:ignore to config Property Changed: ---------------- trunk/server/ Property changes on: trunk/server ___________________________________________________________________ Added: svn:ignore + config This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ch...@us...> - 2010-08-07 18:16:17
|
Revision: 357 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=357&view=rev Author: chozone Date: 2010-08-07 18:16:11 +0000 (Sat, 07 Aug 2010) Log Message: ----------- [Server] * Added import of hashlib in functions.py (woops :$) Modified Paths: -------------- trunk/server/functions.py Modified: trunk/server/functions.py =================================================================== --- trunk/server/functions.py 2010-08-07 17:51:21 UTC (rev 356) +++ trunk/server/functions.py 2010-08-07 18:16:11 UTC (rev 357) @@ -15,7 +15,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import os, sys, time +import os, sys, time, hashlib import database This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 15:52:52
|
Revision: 355 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=355&view=rev Author: BlueWolf_ Date: 2010-08-07 15:52:43 +0000 (Sat, 07 Aug 2010) Log Message: ----------- GUI is slowly starting to work! I also changed all the self.sh's to plain sh Modified Paths: -------------- trunk/client/VP.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/VP.py 2010-08-07 15:52:43 UTC (rev 355) @@ -28,67 +28,85 @@ class Main(): def __init__(self): - self.sh = {} + sh['has_focus'] = True + sh['has_hover'] = True # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' pygame.init() pygame.display.set_caption('Virtual Playground') - self.sh['screen'] = pygame.display.set_mode((1000, 700)) + sh['screen'] = pygame.display.set_mode((1000, 700)) #icon = load_image('img','icon.png') #pygame.display.set_icon(icon) pygame.key.set_repeat(250, 40) pygame.scrap.init() self.clock = pygame.time.Clock() - self.sh['main'] = self + sh['main'] = self # Give the surfaces a way to blit itself - self.sh['update'] = self.update + sh['update'] = self.update self.updaterect = [] self.updatewaiting = False # Create all our surfaces - self.sh['playground'] = Playground(self.sh) - self.sh['layout'] = Layout(self.sh) - self.sh['windows'] = Windows(self.sh) + sh['playground'] = Playground() + sh['layout'] = Layout() + sh['windows'] = Windows() self.update() # Connect to the server - self.sh['client'] = core.Client({ + sh['client'] = core.Client({ 'app_name': "Virtual Playground", 'app_version': VERSION}, - Callback(self.sh)) + Callback()) self.changestatus("connecting") - self.sh['client'].connect('localhost', 6653) + sh['client'].connect('localhost', 6653) # Wait for all the events to come try: while 1: ev = pygame.event.wait() - + if ev.type == QUIT: break if ev.type == MOUSEMOTION: + # Prevent this event from overflowing the queue. Always + # return the position right now and remove al other + # mousemotions in the queue + pos = pygame.mouse.get_pos() pygame.event.clear(MOUSEMOTION) + ev = pygame.event.Event(MOUSEMOTION, + buttons = ev.buttons, + pos = pos) + + # As (sometimes) the mouse focus doesn't get through when + # switching workspaces (Linux), this should "fix" it + sh['has_hover'] = True + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse focus + sh['has_hover'] = (ev.gain == 1) + elif ev.state == 2: # Window focus + sh['has_focus'] = (ev.gain == 1) + # Send through all the layers - if self.sh['windows'].event(ev): continue - if self.sh['layout'].event(ev): continue - if self.sh['playground'].event(ev): continue + if sh['windows'].event(ev): continue + if sh['layout'].event(ev): continue + if sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly print # Someone decided to close VP (Why??) - try: self.sh['client'].close() + try: sh['client'].close() except: pass sys.exit() @@ -125,21 +143,19 @@ # The actual updating happens here - self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) - self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) - self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + sh['screen'].blit(sh['playground'].surf, rect, rect) + sh['screen'].blit(sh['layout'].surf, rect, rect) + sh['screen'].blit(sh['windows'].surf, rect, rect) pygame.display.update(rect) def changestatus(self, status): - self.sh['playground'].changestatus(status) - self.sh['layout'].changestatus(status) - self.sh['windows'].changestatus(status) + sh['playground'].changestatus(status) + sh['layout'].changestatus(status) + sh['windows'].changestatus(status) class Callback(core.Callback): - def __init__(self, sh): - self.sh = sh def data_received(self, data): print " --> " + repr(data) @@ -152,10 +168,10 @@ def received_rsa(self, public): # We are connected - self.sh['main'].changestatus("login") + sh['main'].changestatus("login") def logged_in(self, username, cid, owner): - self.sh['main'].changestatus("playground") + sh['main'].changestatus("playground") if __name__ == "__main__": Main() Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/gui.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,6 +18,143 @@ from functions import * import random + +class Container(): # A modified version of Object + + def __init__(self, update): + self.rect = Rect(0, 0, 1000, 700) + self.parent_update = update + self.frozen = True # Don't update until everything has been + # loaded + + self.children = [] + self.hover = None + self.focus = None + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() + + def __getitem__(self, key): + for child in self.children: + if child.name == key: + return child + + raise KeyError(key) + + def add(self, objname, name, rect): + """ + Append a child to this object + """ + + if objname == "textbox": + Obj = Textbox + elif objname == "button": + Obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update, self.update_mouse) + self.children.append(obj) + + return obj + + + def update(self, rect = None): + """ + Update this part of the object + """ + + if self.frozen: return + + if rect == None: + rect = self.rect + + # Clear this part of our surface + self.surf.fill([0,0,0,0], rect) + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.blit(new_rect, self.surf, rect) + + self.parent_update(rect) + + def unfreeze(self): + """ + Unfreeze this and all the children and update all of them + """ + + for child in self.children: + child.unfreeze(False) + + self.update_mouse() + self.frozen = False + self.update() + + def update_mouse(self, pos = None): + """ + Get the current mouse position and check if the focus has changed + """ + + if pos == None: pos = pygame.mouse.get_pos() + + if sh['has_hover']: + # Get the current hovered object + hover = self.this_pos(pos) + + # Is it different from the previous check? + if hover != self.hover: + # De-hover the previous one + if self.hover: + self.hover.hover = False + self.hover.update() + + self.hover = hover + + # Hover the current one + if self.hover: + self.hover.hover = True + self.hover.update() + + else: + # Remove the previous hover + if self.hover: + self.hover.hover = False + self.hover.update() + self.hover = None + + + + def event(self, ev): + """ + All the events from pygame should go here + """ + + if self.frozen: return + + if ev.type == MOUSEMOTION: # Mouse movement + self.update_mouse(ev.pos) + + elif ev.type == ACTIVEEVENT and ev.state == 1: # Mouse focus + self.update_mouse() + + def this_pos(self, pos): + # Return the object on this position + + for child in self.children: + if not child.rect.collidepoint(pos): continue + + child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) + + hover = child.this_pos(child_pos) + if hover: return hover + + return None + + class Object(): def __init__(self, name, rect, update, update_mouse): @@ -53,9 +190,9 @@ """ if objname == "textbox": - obj = Text + Obj = Textbox elif objname == "button": - obj = Button + Obj = Button else: raise GuiError("Object '%s' has not been found" % objname) @@ -77,7 +214,7 @@ if self.frozen: return if rect == None: - rect = self.rect + rect = self.rect.move(0, 0) else: # We need to calculate our relative position @@ -87,10 +224,10 @@ def blit(self, rect, surf, onto): """ - Render our object and our childs to this surface + Render our object and our children to this surface """ - # Render ourself and our childs to surf + # Render ourself and our children to surf if self.needs_update: self.render() self.needs_update = False @@ -107,7 +244,7 @@ def unfreeze(self, isparent = True): """ - Unfreeze this and all the childs and update all of them + Unfreeze this and all the children and update all of them """ for child in self.children: @@ -119,92 +256,21 @@ self.update(self.rect) else: self.frozen = False - -class Container(): # A modified version of Object - - def __init__(self, update): - self.rect = Rect(0, 0, 1000, 700) - self.parent_update = update - self.frozen = True # Don't update until everything has been - # loaded - - self.children = [] - self.hover = None - self.focus = None - - # Create a surface where an object blits itself onto - self.surf = pygame.Surface((self.rect.width, self.rect.height), \ - SRCALPHA).convert_alpha() - - def __getitem__(self, key): - for child in self.children: - if child.name == key: - return child + def this_pos(self, pos): + # Return the object on this position - raise KeyError(key) - - def add(self, objname, name, rect): - """ - Append a child to this object - """ - - if objname == "textbox": - Obj = Textbox - elif objname == "button": - Obj = Button - else: - raise GuiError("Object '%s' has not been found" % objname) - - obj = Obj(name, rect, self.update, self.update_mouse) - self.children.append(obj) - - return obj - - - def update(self, rect = None): - """ - Update this part of the object - """ - - if self.frozen: return - - if rect == None: - rect = self.rect - - # Clear this part of our surface - self.surf.fill([0,0,0,0], rect) - - # Find all the children within this rect for child in self.children: - if not rect.colliderect(child.rect): continue + if not child.rect.collidepoint(pos): continue - new_rect = rect.move(-child.rect.left, -child.rect.top) - child.blit(new_rect, self.surf, rect) + child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) + + return child.this_pos(child_pos) - self.parent_update(rect) - - def unfreeze(self): - """ - Unfreeze this and all the childs and update all of them - """ - - for child in self.children: - child.unfreeze(False) - - self.update_mouse() - self.frozen = False - self.update() - - def update_mouse(self): - """ - Get the current mouse position and check if the focus has changed - """ - - print "mousecheck" - - + return self + + class Textbox(Object): def __defaults__(self): @@ -268,13 +334,13 @@ if self.style == "login": # Which state do we need? - if self.focus: + if self.hover: top = 37 else: top = 0 self.surf.blit(self.backgroundsurf, (0,0), \ - (0,top, self.rect.width, 37)) + (0, top, self.rect.width, 37)) class GuiError(Exception): Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/layout.py 2010-08-07 15:52:43 UTC (rev 355) @@ -24,9 +24,7 @@ class Layout(): - def __init__(self, sh): - self.sh = sh - + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() self.status = None @@ -109,7 +107,7 @@ self.surf.blit(self.topbar, rect, rect2) - self.sh['update']((0,0, 1000, 65)) + sh['update']((0,0, 1000, 65)) def topbarcursor(self, pos): if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/playground.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,9 +18,8 @@ from functions import * class Playground(): - def __init__(self, sh): - self.sh = sh - + + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) @@ -42,18 +41,18 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("test123", sha1("test123").hexdigest()) + sh['client'].login("test123", sha1("test123").hexdigest()) elif ev.type == KEYDOWN and ev.unicode == "r": # Fake signup - self.sh['client'].signup("test123", sha1("test123").hexdigest(), + sh['client'].signup("test123", sha1("test123").hexdigest(), { "realname": "Pietje Precies", "gender": "M" }) - #if self.logingui != None: - # self.logingui.event(ev) + if self.logingui != None: + self.logingui.event(ev) @@ -74,7 +73,7 @@ self.logingui = None self.surf.fill([0,0,0]) - self.sh['update']() + sh['update']() if status == "connecting": @@ -119,7 +118,7 @@ posleft = (1000/2)-(text.get_size()[0]/2) self.surf.blit(text, (posleft, 330)) - self.sh['update']() + sh['update']() def drawlogingui(self, rect): print "GUIupdate", rect @@ -128,4 +127,4 @@ self.surf.blit(self.loginbox, (292, 256)) self.surf.blit(self.logingui.surf, rect, rect) - self.sh['update'](rect) + sh['update'](rect) Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/windows.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,9 +18,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Windows(): - def __init__(self, sh): - self.sh = sh - + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() def event(self, ev): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-03 22:21:11
|
Revision: 354 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=354&view=rev Author: BlueWolf_ Date: 2010-08-03 22:21:05 +0000 (Tue, 03 Aug 2010) Log Message: ----------- The GUI so far. Looks pretty solid. Will be adding events soon Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Added Paths: ----------- trunk/client/images/gui/ trunk/client/images/gui/text_login.png Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-03 19:13:58 UTC (rev 353) +++ trunk/client/gui.py 2010-08-03 22:21:05 UTC (rev 354) @@ -16,24 +16,29 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from functions import * +import random class Object(): - def __init__(self, name, rect, update): + def __init__(self, name, rect, update, update_mouse): self.name = name self.rect = Rect(rect) self.parent_update = update + self.update_mouse = update_mouse + self.needs_update = False + self.frozen = True # Don't update until everything has been + # loaded self.children = [] self.hover = False self.focus = False - # Load the defaults - self.__defaults__() - # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() + + # Load the defaults + self.__defaults__() def __getitem__(self, key): for child in self.children: @@ -43,6 +48,10 @@ raise KeyError(key) def add(self, objname, name, rect): + """ + Append a child to this object + """ + if objname == "textbox": obj = Text elif objname == "button": @@ -50,28 +59,80 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update) + obj = Obj(name, rect, self.update, self.update_mouse) self.children.append(obj) return obj - def update(self, rect): + def update(self, rect = None): + """ + Update this part of the object + """ + # Send a message to our parent, telling them this rect needs to be # updated - # We need to calculate our relative position - return rect.move(self.rect.left, self.rect.top) + self.needs_update = True + + if self.frozen: return + + if rect == None: + rect = self.rect + + else: + # We need to calculate our relative position + rect.move_ip(self.rect.left, self.rect.top) + self.parent_update(rect) + + def blit(self, rect, surf, onto): + """ + Render our object and our childs to this surface + """ + + # Render ourself and our childs to surf + if self.needs_update: + self.render() + self.needs_update = False + + surf.blit(self.surf, onto, rect) + + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.blit(new_rect, surf, onto) + + def unfreeze(self, isparent = True): + """ + Unfreeze this and all the childs and update all of them + """ + + for child in self.children: + child.unfreeze(False) + + if isparent: + self.update_mouse() + self.frozen = False + self.update(self.rect) + else: + self.frozen = False + + + class Container(): # A modified version of Object - def __init__(self, size, update): - self.rect = Rect(0,0,size[0], size[1]) + def __init__(self, update): + self.rect = Rect(0, 0, 1000, 700) self.parent_update = update + self.frozen = True # Don't update until everything has been + # loaded self.children = [] - self.hover = False - self.focus = False + self.hover = None + self.focus = None # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ @@ -85,6 +146,10 @@ raise KeyError(key) def add(self, objname, name, rect): + """ + Append a child to this object + """ + if objname == "textbox": Obj = Textbox elif objname == "button": @@ -92,63 +157,97 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update) + obj = Obj(name, rect, self.update, self.update_mouse) self.children.append(obj) return obj - def update(self, rect): + def update(self, rect = None): + """ + Update this part of the object + """ + + if self.frozen: return + + if rect == None: + rect = self.rect + # Clear this part of our surface - self.surf.fill(rect, [0,0,0,0]) + self.surf.fill([0,0,0,0], rect) # Find all the children within this rect for child in self.children: if not rect.colliderect(child.rect): continue new_rect = rect.move(-child.rect.left, -child.rect.top) - child.render(rect, surf, rect) + child.blit(new_rect, self.surf, rect) self.parent_update(rect) - - + + def unfreeze(self): + """ + Unfreeze this and all the childs and update all of them + """ - - + for child in self.children: + child.unfreeze(False) + + self.update_mouse() + self.frozen = False + self.update() + + def update_mouse(self): + """ + Get the current mouse position and check if the focus has changed + """ + + print "mousecheck" + + class Textbox(Object): def __defaults__(self): self.input = "" self.cursorpos = 0 self.style = None - self.layout = None self.type = "text" - - def render(self, correction, surf): - if self.layout == None: return - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size + self.backgroundsurf = pygame.Surface((self.rect.width, \ + self.rect.height*2), SRCALPHA).convert_alpha() - print correction, pos - surf.fill([255,0,0], pos) - - def update(self): - pass - def set_style(self, style): """ Possible styles: * login """ - if style == "text": - pass - elif style == "login": - self.layout = load_image(True, "images", "gui", "text_login.png") + if style == "login": + if self.rect.height != 37: + raise GuiError("Height should be 37") + if self.rect.width < 25: + raise GuiError("Width should be 25 or bigger ") + + layoutimg = load_image(True, "images", "gui", "text_login.png") + + # Create backgroundsurf + self.backgroundsurf.fill([0,0,0,0]) + + # Left + self.backgroundsurf.blit(layoutimg, (0, 0), (0, 0, 12, 74)) + # Right + self.backgroundsurf.blit(layoutimg, (self.rect.width-12, 0), \ + (15, 0, 12, 74)) + # Middle + middle = pygame.Surface((1, 74), SRCALPHA).convert_alpha() + middle.blit(layoutimg, (0, 0,), (13, 0, 1, 74)) + middle = pygame.transform.scale(middle, (self.rect.width-24, 74)) + self.backgroundsurf.blit(middle, (12, 0)) + else: raise GuiError("Style '%s' has not been found" % style) self.style = style + self.update() def set_type(self, type): """ @@ -160,20 +259,23 @@ raise GuiError("Type '%s' has not been found" % type) self.type = type + self.update() + + def render(self): + if self.backgroundsurf == None: return - - -class Button(Object): - - def __defaults__(self): - self.caption = "" - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size + self.surf.fill([0,0,0,0]) - surf.fill([0,0,255], pos) + if self.style == "login": + # Which state do we need? + if self.focus: + top = 37 + else: + top = 0 + + self.surf.blit(self.backgroundsurf, (0,0), \ + (0,top, self.rect.width, 37)) + - class GuiError(Exception): pass Added: trunk/client/images/gui/text_login.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/gui/text_login.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-03 19:13:58 UTC (rev 353) +++ trunk/client/playground.py 2010-08-03 22:21:05 UTC (rev 354) @@ -37,6 +37,8 @@ def event(self, ev): if self.status == "login": + + # Some temporary debug stuff if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") @@ -49,6 +51,11 @@ "realname": "Pietje Precies", "gender": "M" }) + + #if self.logingui != None: + # self.logingui.event(ev) + + def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] @@ -93,22 +100,19 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui((417,189), self.drawlogingui) - - username = self.logingui.add("textbox", "usr", (0,0, 417, 50)) - #username = gui.Text("username", (0,0, 417, 50)) - #username.set_style("login") + self.logingui = gui(self.drawlogingui) - #password = gui.Text("password", (0,50, 417, 50)) - #password.set_style("login") - #password.set_type("password") + username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) + username.set_style("login") + password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) + password.set_style("login") + password.set_type("password") + #login = gui.Button("login", (0, 100, 417, 50)) - # [TODO] Give mouseposition + self.logingui.unfreeze() - #self.logingui.renderall() - elif status == "logging in": text = self.loginfont.render("Logging in...", True, (132,125,114)) @@ -118,11 +122,10 @@ self.sh['update']() def drawlogingui(self, rect): - print rect - rect_main = rect.move(292,256) + print "GUIupdate", rect - self.surf.blit(self.loginbg, rect_main, rect_main) - self.surf.blit(self.loginbox, rect_main, rect) - self.surf.blit(self.logingui.surf, rect_main, rect) + self.surf.blit(self.loginbg, rect, rect) + self.surf.blit(self.loginbox, (292, 256)) + self.surf.blit(self.logingui.surf, rect, rect) - self.sh['update'](rect_main) + self.sh['update'](rect) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-03 19:14:06
|
Revision: 353 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=353&view=rev Author: BlueWolf_ Date: 2010-08-03 19:13:58 +0000 (Tue, 03 Aug 2010) Log Message: ----------- Added the login GIMP files Modified Paths: -------------- res/images/xcf/loginbg.xcf Added Paths: ----------- res/images/xcf/login-gui.xcf Added: res/images/xcf/login-gui.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/login-gui.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: res/images/xcf/loginbg.xcf =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-02 20:41:15
|
Revision: 352 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=352&view=rev Author: BlueWolf_ Date: 2010-08-02 20:41:09 +0000 (Mon, 02 Aug 2010) Log Message: ----------- Modified Paths: -------------- trunk/client/functions.py trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/functions.py 2010-08-02 20:41:09 UTC (rev 352) @@ -19,9 +19,7 @@ from pygame.locals import * from hashlib import sha1 import core -import gui - VERSION = "0.0.1" # This will be used to [sh]are all variables, functions and classes across the @@ -51,3 +49,9 @@ print 'Cannot load image:', fullname raise SystemExit, message return image + + +# GUI needs the functions again. That's why it has to be imported after all +# functions have been defined +import gui +gui = gui.Container Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/gui.py 2010-08-02 20:41:09 UTC (rev 352) @@ -17,74 +17,152 @@ from functions import * -class Plane(): - - def __init__(self, update, width, height): - self.update = update - self.width = width - self.height = height - self.surf = pygame.Surface((self.width, self.height), SRCALPHA) \ - .convert_alpha() - self.norender = True - - self.childs = {} - - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - def renderall(self): - self.norender = False - for child in self.childs.values(): - child.renderall(Rect(0,0,0,0), self.surf) - - self.update(Rect(0,0, self.width, self.height)) - - class Object(): - def __init__(self, name, rect): + def __init__(self, name, rect, update): self.name = name self.rect = Rect(rect) - self.childs = {} + self.parent_update = update + + self.children = [] + self.hover = False self.focus = False - self.hover = False # Load the defaults self.__defaults__() + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() def __getitem__(self, key): - return self.childs[key] + for child in self.children: + if child.name == key: + return child + + raise KeyError(key) - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj + def add(self, objname, name, rect): + if objname == "textbox": + obj = Text + elif objname == "button": + obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update) + self.children.append(obj) + + return obj - def renderall(self, correction, surf): - # First render ourself - self.render(correction, surf) + def update(self, rect): + # Send a message to our parent, telling them this rect needs to be + # updated - # Then render our childs - for child in self.childs.values(): - child.renderall(correction.move(self.rect.topleft), surf) + # We need to calculate our relative position + return rect.move(self.rect.left, self.rect.top) + + +class Container(): # A modified version of Object + + def __init__(self, size, update): + self.rect = Rect(0,0,size[0], size[1]) + self.parent_update = update + + self.children = [] + self.hover = False + self.focus = False + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() + + def __getitem__(self, key): + for child in self.children: + if child.name == key: + return child + raise KeyError(key) + + def add(self, objname, name, rect): + if objname == "textbox": + Obj = Textbox + elif objname == "button": + Obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update) + self.children.append(obj) + + return obj + + + def update(self, rect): + # Clear this part of our surface + self.surf.fill(rect, [0,0,0,0]) + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.render(rect, surf, rect) + + self.parent_update(rect) + + + -class Text(Object): +class Textbox(Object): + def __defaults__(self): self.input = "" self.cursorpos = 0 + self.style = None + self.layout = None + self.type = "text" def render(self, correction, surf): + if self.layout == None: return + pos = correction.move(self.rect.topleft) pos.size = self.rect.size + print correction, pos surf.fill([255,0,0], pos) + def update(self): + pass + + def set_style(self, style): + """ + Possible styles: + * login + """ + if style == "text": + pass + elif style == "login": + self.layout = load_image(True, "images", "gui", "text_login.png") + else: + raise GuiError("Style '%s' has not been found" % style) + + self.style = style + def set_type(self, type): + """ + Possible types: + * text + * password + """ + if type not in ("text", "password"): + raise GuiError("Type '%s' has not been found" % type) + + self.type = type + + + class Button(Object): def __defaults__(self): @@ -96,3 +174,6 @@ surf.fill([0,0,255], pos) + +class GuiError(Exception): + pass Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/playground.py 2010-08-02 20:41:09 UTC (rev 352) @@ -91,14 +91,22 @@ elif status == "login": self.surf.blit(self.loginbox, (292,256)) + # Create login-field - #self.logingui = gui.Plane(self.drawlogingui, 417,189) + self.logingui = gui((417,189), self.drawlogingui) + + username = self.logingui.add("textbox", "usr", (0,0, 417, 50)) #username = gui.Text("username", (0,0, 417, 50)) + #username.set_style("login") + #password = gui.Text("password", (0,50, 417, 50)) + #password.set_style("login") + #password.set_type("password") + #login = gui.Button("login", (0, 100, 417, 50)) - #self.logingui.add(username, password, login) # [TODO] Give mouseposition + #self.logingui.renderall() @@ -110,6 +118,7 @@ self.sh['update']() def drawlogingui(self, rect): + print rect rect_main = rect.move(292,256) self.surf.blit(self.loginbg, rect_main, rect_main) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-01 22:16:26
|
Revision: 351 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=351&view=rev Author: BlueWolf_ Date: 2010-08-01 22:16:19 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Code is still the same but I changed all tabs. 8 tabs are now 4 spaces. Modified Paths: -------------- trunk/client/VP.py trunk/client/core/__init__.py trunk/client/core/callback.py trunk/client/core/client.py trunk/client/core/parser.py trunk/client/functions.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/VP.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,5 +1,22 @@ #!/usr/bin/env python +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * import core @@ -10,138 +27,135 @@ class Main(): - def __init__(self): - self.sh = {} - - # Fire up pygame - os.environ['SDL_VIDEO_CENTERED']='1' - pygame.init() - pygame.display.set_caption('Virtual Playground') - self.sh['screen'] = pygame.display.set_mode((1000, 700)) - #icon = load_image('img','icon.png') - #pygame.display.set_icon(icon) - pygame.key.set_repeat(250, 40) - pygame.scrap.init() - self.clock = pygame.time.Clock() - - self.sh['main'] = self - - # Give the surfaces a way to blit itself - self.sh['update'] = self.update - self.updaterect = [] - self.updatewaiting = False - - - # Create all our surfaces - self.sh['playground'] = Playground(self.sh) - self.sh['layout'] = Layout(self.sh) - self.sh['windows'] = Windows(self.sh) - - self.update() - - - # Connect to the server - self.sh['client'] = core.Client({ - 'app_name': "Virtual Playground", - 'app_version': VERSION}, - Callback(self.sh)) - - self.changestatus("connecting") - self.sh['client'].connect('localhost', 6653) - - - # Wait for all the events to come - try: - while 1: - ev = pygame.event.wait() - - if ev.type == QUIT: break - - if ev.type == MOUSEMOTION: - pos = pygame.mouse.get_pos() - pygame.event.clear(MOUSEMOTION) - - # Send through all the layers - if self.sh['windows'].event(ev): continue - if self.sh['layout'].event(ev): continue - if self.sh['playground'].event(ev): continue - - - except KeyboardInterrupt: # Note: this does not work properly - print - - # Someone decided to close VP (Why??) - try: self.sh['client'].close() - except: pass - sys.exit() - + def __init__(self): + self.sh = {} + + # Fire up pygame + os.environ['SDL_VIDEO_CENTERED']='1' + pygame.init() + pygame.display.set_caption('Virtual Playground') + self.sh['screen'] = pygame.display.set_mode((1000, 700)) + #icon = load_image('img','icon.png') + #pygame.display.set_icon(icon) + pygame.key.set_repeat(250, 40) + pygame.scrap.init() + self.clock = pygame.time.Clock() + + self.sh['main'] = self + + # Give the surfaces a way to blit itself + self.sh['update'] = self.update + self.updaterect = [] + self.updatewaiting = False + + + # Create all our surfaces + self.sh['playground'] = Playground(self.sh) + self.sh['layout'] = Layout(self.sh) + self.sh['windows'] = Windows(self.sh) + + self.update() + + + # Connect to the server + self.sh['client'] = core.Client({ + 'app_name': "Virtual Playground", + 'app_version': VERSION}, + Callback(self.sh)) + + self.changestatus("connecting") + self.sh['client'].connect('localhost', 6653) + + + # Wait for all the events to come + try: + while 1: + ev = pygame.event.wait() + + if ev.type == QUIT: break + + if ev.type == MOUSEMOTION: + pos = pygame.mouse.get_pos() + pygame.event.clear(MOUSEMOTION) + + # Send through all the layers + if self.sh['windows'].event(ev): continue + if self.sh['layout'].event(ev): continue + if self.sh['playground'].event(ev): continue + + + except KeyboardInterrupt: # Note: this does not work properly + print + + # Someone decided to close VP (Why??) + try: self.sh['client'].close() + except: pass + sys.exit() + - def update(self, rect = Rect(0,0, 1000, 700)): - """ - Blit all the surfaces (playground, layout and windows) together - and update the screen - """ - - # The following code will prevent it from going crazy on the cpu - # aka: using unlimited FPS. This will limit the FPS to 50 and - # will remember everything that should be updated in the mean - # time - - self.updaterect.append(rect) - if self.updatewaiting: - # Rect is saved. Will be updated once self.clock stops - # blocking - return - - # When there are more updates from here one, they will be saved - # without being updated immediately. We will do that once tick - # stops blocking - self.updatewaiting = True - self.clock.tick(50) - - # Get all the rects to update - if len(self.updaterect) == 1: - rects = self.updaterect[0] - else: - rects = self.updaterect[0].unionall(self.updaterect[1:]) - - self.updaterect = [] - self.updatewaiting = False - - - # The actual updating happens here - self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) - self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) - self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) - - pygame.display.update(rect) - - def changestatus(self, status): - self.sh['playground'].changestatus(status) - self.sh['layout'].changestatus(status) - self.sh['windows'].changestatus(status) + def update(self, rect = Rect(0,0, 1000, 700)): + """ + Blit all the surfaces (playground, layout and windows) together + and update the screen + """ + + # The following code will prevent it from going crazy on the cpu. + # aka: using unlimited FPS. This will limit the FPS to 50 and will + # remember everything that should be updated in the mean time + + self.updaterect.append(rect) + if self.updatewaiting: + # Rect is saved. Will be updated once self.clock stops blocking + return + + # When there are more updates from here one, they will be saved without + # being updated immediately. We will do that once tick stops blocking + self.updatewaiting = True + self.clock.tick(50) + + # Get all the rects to update + if len(self.updaterect) == 1: + rects = self.updaterect[0] + else: + rects = self.updaterect[0].unionall(self.updaterect[1:]) + + self.updaterect = [] + self.updatewaiting = False + + + # The actual updating happens here + self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) + self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) + self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + + pygame.display.update(rect) + + def changestatus(self, status): + self.sh['playground'].changestatus(status) + self.sh['layout'].changestatus(status) + self.sh['windows'].changestatus(status) class Callback(core.Callback): - def __init__(self, sh): - self.sh = sh - - def data_received(self, data): - print " --> " + repr(data) - - def data_send(self, data): - print " <-- " + repr(data) - - def disconnect(self, reason): - print "Server disconnected: " + reason - - def received_rsa(self, public): - # We are connected - self.sh['main'].changestatus("login") - - def logged_in(self, username, cid, owner): - self.sh['main'].changestatus("playground") + def __init__(self, sh): + self.sh = sh + + def data_received(self, data): + print " --> " + repr(data) + + def data_send(self, data): + print " <-- " + repr(data) + + def disconnect(self, reason): + print "Server disconnected: " + reason + + def received_rsa(self, public): + # We are connected + self.sh['main'].changestatus("login") + + def logged_in(self, username, cid, owner): + self.sh['main'].changestatus("playground") if __name__ == "__main__": Main() Modified: trunk/client/core/__init__.py =================================================================== --- trunk/client/core/__init__.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/__init__.py 2010-08-01 22:16:19 UTC (rev 351) @@ -28,10 +28,10 @@ The Client is the core. You need to create your own callback class, which should inherit the functions of Callback. You get feedback from your callback-class. >>> class callback(Callback): -... def connect(self): -... print "Connect!" -... def logged_in(self, username, uid, cid): - print "I'm logged in!" +... def connect(self): +... print "Connect!" +... def logged_in(self, username, uid, cid): + print "I'm logged in!" Because it inherits all the (empty) functions from Callback, you don't have to create all the functions yourself. Also, in help(Callback) you see all possible @@ -40,14 +40,14 @@ The next thing is the config. See help(Client) for all the available config-options. >>> config = { -... "app_name": "My awesome application", -... "app_version": "2.0" +... "app_name": "My awesome application", +... "app_version": "2.0" ... } Start the core. >>> client = Client(config, callback()) >>> client.connect("my.host.com", 1234, "Username", \ -... sha.new("Password").hexdigest()) +... sha.new("Password").hexdigest()) If you have the server online and your login is correct, it will print: Connect! Modified: trunk/client/core/callback.py =================================================================== --- trunk/client/core/callback.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/callback.py 2010-08-01 22:16:19 UTC (rev 351) @@ -16,134 +16,126 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Callback: - def connected(self): - """ - When the connection is made, this will be called. Note that the - server can still kick the connection because it is full. You - should not client.login here, because the server still has to - send a rsa-key. See callback.received_rsa for this event. + def connected(self): + """ + When the connection is made, this will be called. Note that the server + can still kick the connection because it is full. You should not + client.login here, because the server still has to send a rsa-key. See + callback.received_rsa for this event. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def received_rsa(self, public): - """ - When a connection is made, the server will generate a rsa-key. - The client has to wait for this, before logging in. After this - event, you can use client.login (if you haven't specified a - login at client.connect) - - public: - The generated public rsa-key. It is a dict with 2 - values: e and n. It's used for encoding the password - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def disconnected(self, reason): - """ - This is called when the connection dies. For example when you - close the connection manually, the server kicks you, your modem - explodes or your cat eates the LAN cable. - - reason: - A string, representing the reason why it disconnected. - It currently has these options: - * "closed" - Server dropped the connection - unexpectedly - * "full" - Server is full and does not except - - more connections - * "manual" - Client (you) closed the connection - with .close() - * "duplicate" - Another client has logged in on this - account. This connection has been - kicked - * "crash" - A crash happened on the server. Unless - you sent malicious data or you're not - admin of the server, there's nothing - you can do about it - * "gone offline"- The server has just gone offline - - - Return True if you want it to reconnect. To avoid unexpected - behaviour, you should *only* do this when reason is "closed" or - "gone offline"! - If you provided the login in client.connect, it logs in - automatically. - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def data_received(self, data): - """ - Called when we received data from the server. Normally, you - don't need this. - - data: - Dict with the data that has been received - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def data_send(self, data): - """ - Called when we send data to the server. Normally, you - don't need this. - - data: - Dict with the data that will be send. - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def logged_in(self, username, cid, owner): - """ - Called when we are logged in. - - username: - The username for this user. Use this, instead what the - user typed in, because this has the right caps. Also - available in client.username. - cid: - The unique client-id for this connection. Also available - in client.cid - owner: - This is the owner-username for this bot. This variable - will be None when you log in as a normal user - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - - pass - - def failed_logging_in(self, reason): - """ - This happens when the user could not log in. You can safely use - client.login again. - - reason: - The reason why the user could not log in: - * "bad login" - The username and/or password is wrong. - * "login not allowed" - You may not log in right now - * "bot limit reached" - There're to much bots logged - in for your account - * "login blocked" - You (or your IP) are blocked - * "duplicate user" - There is already someone - online with this username - """ - - pass + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def received_rsa(self, public): + """ + When a connection is made, the server will generate a rsa-key. The + client has to wait for this, before logging in. After this event, you + can use client.login (if you haven't specified a login at client.connect) + + public: + The generated public rsa-key. It is a dict with 2 values: e and n. + It's used for encoding the password + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def disconnected(self, reason): + """ + This is called when the connection dies. For example when you close the + connection manually, the server kicks you, your modem explodes or your + cat ate the LAN cable. + + reason: + A string, representing the reason why it disconnected. + It currently has these options: + * "closed" - Server dropped the connection unexpectedly + * "full" - Server is full and does not except more + connections + * "manual" - Client (you) closed the connection with .close() + * "duplicate" - Another client has logged in on this account. + This connection has been kicked + * "crash" - A crash happened on the server. Unless you sent + malicious data or you're not admin of the server, + there's nothing you can do about it. Live with it. + * "gone offline"- The server has just gone offline + + + Return True if you want it to reconnect. To avoid unexpected behaviour, + you should *only* do this when reason is "closed" or "gone offline"! If + you provided the login in client.connect, it logs in automatically. + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def data_received(self, data): + """ + Called when we received data from the server. Normally, you don't need + this. + + data: + Dict with the data that has been received + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def data_send(self, data): + """ + Called when we send data to the server. Normally, you don't need this. + + data: + Dict with the data that will be send. + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def logged_in(self, username, cid, owner): + """ + Called when we are logged in. + + username: + The username for this user. Use this, instead what the user typed + in, because this has the right caps. Also available in + client.username + cid: + The unique client-id for this connection. Also available in + client.cid + owner: + This is the owner-username for this bot. This variable will be None + when you log in as a normal user + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + + pass + + def failed_logging_in(self, reason): + """ + This happens when the user could not log in. You can safely use + client.login again + + reason: + The reason why the user could not log in: + * "bad login" - The username and/or password is wrong. + * "login not allowed" - You may not log in right now + * "bot limit reached" - There're to much bots logged in for + your account + * "login blocked" - You (or your IP) are blocked + * "duplicate user" - There is already someone online with + this username + """ + + pass Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/client.py 2010-08-01 22:16:19 UTC (rev 351) @@ -24,356 +24,350 @@ class Client(threading.Thread): - """ - This is the client-core for Virtual Playground. This will handle the - connections and data to and from the server. - - config: - This should be a dict with settings for the client. See the - bottom of this documentation for a list of all possible - settings. - - callback_class: - The callback class will be used to notify you for certain events - that happens in the core. It has to look something like this: - - class Callback(core.Callback): - ... - - See the doc in core.Callback for more information about this. - - -------- - - The settings: - -app_name - The name of your program. Will be send when logging in. - -app_version - The version of your program. Will be send when logging - in. Should be a string. - """ - - def __init__(self, config, callback_class): - - self.__call = callback_class - self.__sock = None - self.__pinger = None - - # This will be available ([sh]ared) to al modules in the core - self.__sh = {} - - self.__sh['call'] = callback_class - self.__sh['core'] = self - self.__sh['isbot'] = None - - # Create all default settings - self.__config_default(config) - self.__sh['config'] = config - - # So the client knows if we are online. Is used for - # disconnecting - self.__sh['is_online'] = False - - # Treading-event so that run() waits before it's allowed to - # connect - self.__do_connect = threading.Event() - self.__do_connect.clear() - - # Auto log in after connecting. - self.__sh['auto_login'] = () - - # RSA - self.__sh['rsakey'] = None - - # Info after logging in - self.username = None - self.owner = None - self.cid = None # Connection-id - - # Class that parsers all incomming data - self.__parse = Parser(self.__sh) - - threading.Thread.__init__(self) - - self.setDaemon(True) - self.start() - - - def __config_default(self, config): - config['app_name'] = str(config.get('app_name', __name__)) - config['app_version'] = str(config.get('app_version', - __version__)) - - - def connect(self, host, port): - """ - Will (try to) connect to the server on `host`:`port`. - If you want to reconnect, you have to close the connection - first, if it's still open. - - You can do Client.login and Client.bot_login directly after - this. It will be done as soon as it has received a rsa-key. - """ - - self.__host = host - self.__port = port - - if self.__sock: - raise ConnectionError("You are already connected!") - - self.__do_connect.set() # Releasing the hounds - - - def run(self): - """ - Used by threading, not for external usage. - """ - while 1: - self.__do_connect.wait() # Wait to connect - - self.__sh['is_online'] = True - disconnect_reason = None - - self.__sock = socket.socket(socket.AF_INET, - socket.SOCK_STREAM) - - while 1: - try: - self.__sock.connect((self.__host, - self.__port)) - break - except: - time.sleep(1) - - self.__call.connected() - - self.__pinger = self.__Pinger(self.send) + """ + This is the client-core for Virtual Playground. This will handle the + connections and data to and from the server. + + config: + This should be a dict with settings for the client. See the bottom of + this documentation for a list of all possible settings. + + callback_class: + The callback class will be used to notify you for certain events that + happens in the core. It has to look something like this: + + class Callback(core.Callback): + ... + + See the doc in core.Callback for more information about this. + + -------- + + The settings: + -app_name + The name of your program. Will be send when logging in. + -app_version + The version of your program. Will be send when logging + in. Should be a string. + """ + + def __init__(self, config, callback_class): + + self.__call = callback_class + self.__sock = None + self.__pinger = None + + # This will be available ([sh]ared) to al modules in the core + self.__sh = {} + + self.__sh['call'] = callback_class + self.__sh['core'] = self + self.__sh['isbot'] = None + + # Create all default settings + self.__config_default(config) + self.__sh['config'] = config + + # So the client knows if we are online. Is used for + # disconnecting + self.__sh['is_online'] = False + + # Treading-event so that run() waits before it's allowed to connect + self.__do_connect = threading.Event() + self.__do_connect.clear() + + # Auto log in after connecting. + self.__sh['auto_login'] = () + + # RSA + self.__sh['rsakey'] = None + + # Info after logging in + self.username = None + self.owner = None + self.cid = None # Connection-id + + # Class that parsers all incomming data + self.__parse = Parser(self.__sh) + + threading.Thread.__init__(self) + + self.setDaemon(True) + self.start() + + + def __config_default(self, config): + config['app_name'] = str(config.get('app_name', __name__)) + config['app_version'] = str(config.get('app_version', __version__)) + + + def connect(self, host, port): + """ + Will (try to) connect to the server on `host`:`port`. If you want to + reconnect, you have to close the connection first, if it's still open. + + You can do Client.login and Client.bot_login directly after this. It + will be done as soon as it has received a rsa-key. + """ + + self.__host = host + self.__port = port + + if self.__sock: + raise ConnectionError("You are already connected!") + + self.__do_connect.set() # Releasing the hounds + + + def run(self): + """ + Used by threading, not for external usage. + """ + while 1: + self.__do_connect.wait() # Wait to connect + + self.__sh['is_online'] = True + disconnect_reason = None + + self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + while 1: + try: + self.__sock.connect((self.__host, self.__port)) + break + except: + time.sleep(1) + + self.__call.connected() + + self.__pinger = self.__Pinger(self.send) - - #Infinite loop that receives data - buffer = '' - while 1: - try: - data = self.__sock.recv(1024) - except: - disconnect_reason = "closed" - break - if not data: - disconnect_reason = "closed" - break - - buffer += data - - #Each dataset must end with a delimiter: chr(1) - if chr(1) not in buffer: continue - - data = buffer.split(chr(1)) - buffer = data[-1] - data = data[:-1] - - for msg in data: - self.__parse(simplejson.loads(msg)) - - if self.__sh['is_online']: - self.close(disconnect_reason) - - def login(self, usr, pwd): - """ - Log in to the server as a normal user. If the RSA-key wasn't - received yet, it will login after is has received the key. pwd - is expected to be sha1. - - >>> import hashlib - >>> hashlib.sha1("MyVerySecretPassword").hexdigest() - 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' - """ - - if self.cid != None: - raise LoginError("You are already logged in") - - # Save this - self.__sh['auto_login'] = (self.login, (usr, pwd)) - - # Wait for the rsa-key to arrive - if not self.__sh['rsakey']: return - - if not self.__sock: - raise ConnectionError("You are not connected!") - - self.__sh['isbot'] = False - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - # Log in - self.send("login", { - "usr": usr, - "pwd": pwd, - "bot": False, - "for": "VP", - "client": ( self.__sh['config']['app_name'], - self.__sh['config']['app_version'] - ), - "version": __version__ - }) - - def login_bot(self, owner, pwd, screenname): - """ - Log in as a bot. If the RSA-key wasn't received yet, it will - login after is has received the key. pwd is expected to be sha1. - - >>> import hashlib - >>> hashlib.sha1("MyVerySecretPassword").hexdigest() - 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' - """ - - if self.cid != None: - raise LoginError("You are already logged in") - - # Save this - self.__sh['auto_login'] = (self.login_bot, \ - (owner, pwd, screenname)) - - # Wait for the rsa-key to arrive - if not self.__sh['rsakey']: return - - if not self.__sock: - raise ConnectionError("You are not connected!") - - self.__sh['isbot'] = True - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - # Log in - self.send("login", { - "usr": owner, - "pwd": pwd, - "name": screenname, - "bot": True, - "for": "VP", - "client": ( self.__sh['config']['app_name'], - self.__sh['config']['app_version'] - ), - "version": __version__ - }) - - - def signup(self, usr, pwd, extra = {}): - """ - Create a new account with on the server. You should have a - connection first before using this. - """ - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - if self.cid != None: - raise SignupError("You are already logged in") - - - # Sign up - self.send("signup", { - "usr": usr, - "pwd": pwd, - "extra": extra - }) - - - - def send(self, data_header, data_body = {}): - """ - Sends `data_body` of type `data_header` to the server. It will - automatically be encoded as JSON, and the delimeter character - (chr(1)) will be send automatically too. - `Data_header` is a string, `data_body` a dict. - """ - - self.__call.data_send({data_header:data_body}) - data = simplejson.dumps({data_header:data_body}) - try: - self.__sock.send(data + chr(1)) - except: pass - - - def close(self, reason = "manual"): - """ - Will close the connection to the server. If the connection is - already down, it will raise an exception. This will trigger the - callback `disconnected`. It may reconnect, depending on the - callback. If not, you can reuse this class by calling `connect`. - """ - - if not self.__sh['is_online']: - if reason == "manual": - # Annoy the user - raise ConnectionError("The connection is " + \ - "already closed!") - else: - return; - - - self.__do_connect.clear() # Block the thread-loop - - self.__sh['is_online'] = False - - if self.__pinger != None: - self.__pinger.cancel() - self.__pinger = None - - # Reset variables - self.__sh['rsakey'] = None - self.username = None - self.owner = None - self.cid = None - - try: self.__sock.shutdown(0) - except: pass - self.__sock.close() - self.__sock = None - - if self.__call.disconnected(reason): - # Reconnect - self.__do_connect.set() - else: - # Remove auto-login - self.__sh['auto_login'] = () - - - class __Pinger(): - def __init__(self, send): - """ - Will ping every 30 seconds for food. If the server - doesn't receive anything from us for 45 sec, it will - drop the connection, because it thinks our computer blew - up or something... - """ - self.running = True + + #Infinite loop that receives data + buffer = '' + while 1: + try: + data = self.__sock.recv(1024) + except: + disconnect_reason = "closed" + break + if not data: + disconnect_reason = "closed" + break + + buffer += data + + #Each dataset must end with a delimiter: chr(1) + if chr(1) not in buffer: continue + + data = buffer.split(chr(1)) + buffer = data[-1] + data = data[:-1] + + for msg in data: + self.__parse(simplejson.loads(msg)) + + if self.__sh['is_online']: + self.close(disconnect_reason) + + def login(self, usr, pwd): + """ + Log in to the server as a normal user. If the RSA-key wasn't received + yet, it will login after is has received the key. pwd is expected to be sha1. + + >>> import hashlib + >>> hashlib.sha1("MyVerySecretPassword").hexdigest() + 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' + """ + + if self.cid != None: + raise LoginError("You are already logged in") + + # Save this + self.__sh['auto_login'] = (self.login, (usr, pwd)) + + # Wait for the rsa-key to arrive + if not self.__sh['rsakey']: return + + if not self.__sock: + raise ConnectionError("You are not connected!") + + self.__sh['isbot'] = False + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + # Log in + self.send("login", { + "usr": usr, + "pwd": pwd, + "bot": False, + "for": "VP", + "client": ( + self.__sh['config']['app_name'], + self.__sh['config']['app_version'] + ), + "version": __version__ + }) + + def login_bot(self, owner, pwd, screenname): + """ + Log in as a bot. If the RSA-key wasn't received yet, it will login after + is has received the key. pwd is expected to be sha1. + + >>> import hashlib + >>> hashlib.sha1("MyVerySecretPassword").hexdigest() + 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' + """ + + if self.cid != None: + raise LoginError("You are already logged in") + + # Save this + self.__sh['auto_login'] = (self.login_bot, (owner, pwd, screenname)) + + # Wait for the rsa-key to arrive + if not self.__sh['rsakey']: return + + if not self.__sock: + raise ConnectionError("You are not connected!") + + self.__sh['isbot'] = True + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + # Log in + self.send("login", { + "usr": owner, + "pwd": pwd, + "name": screenname, + "bot": True, + "for": "VP", + "client": ( + self.__sh['config']['app_name'], + self.__sh['config']['app_version'] + ), + "version": __version__ + }) + + + def signup(self, usr, pwd, extra = {}): + """ + Create a new account with on the server. You should have a connection + first before using this. + """ + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + if self.cid != None: + raise SignupError("You are already logged in") + + + # Sign up + self.send("signup", { + "usr": usr, + "pwd": pwd, + "extra": extra, + "version": __version__ + }) + + + + def send(self, data_header, data_body = {}): + """ + Sends `data_body` of type `data_header` to the server. It will + automatically be encoded as JSON, and the delimeter character (chr(1)) + will be send automatically too. `Data_header` is a string, `data_body` + a dict. + """ + + self.__call.data_send({data_header:data_body}) + data = simplejson.dumps({data_header:data_body}) + try: + self.__sock.send(data + chr(1)) + except: pass + + + def close(self, reason = "manual"): + """ + Will close the connection to the server. If the connection is already + down, it will raise an exception. This will trigger the callback + `disconnected`. It may reconnect, depending on the callback. If not, you + can reuse this class by calling `connect`. + """ + + if not self.__sh['is_online']: + if reason == "manual": + # Annoy the user + raise ConnectionError("The connection is " + \ + "already closed!") + else: + return; + + + self.__do_connect.clear() # Block the thread-loop + + self.__sh['is_online'] = False + + if self.__pinger != None: + self.__pinger.cancel() + self.__pinger = None + + # Reset variables + self.__sh['rsakey'] = None + self.username = None + self.owner = None + self.cid = None + + try: self.__sock.shutdown(0) + except: pass + self.__sock.close() + self.__sock = None + + if self.__call.disconnected(reason): + # Reconnect + self.__do_connect.set() + else: + # Remove auto-login + self.__sh['auto_login'] = () + + + class __Pinger(): + def __init__(self, send): + """ + Will ping every 30 seconds for food. If the server doesn't receive + anything from us for 45 sec, it will drop the connection, because it + thinks our computer blew up or something... + """ + self.running = True - self.send = send - self.timer = threading.Timer(30, self.run) - self.timer.start() + self.send = send + self.timer = threading.Timer(30, self.run) + self.timer.start() - def run(self): - if self.running == False: return + def run(self): + if self.running == False: return - #Ping! - self.send('ping', {}) + #Ping! + self.send('ping', {}) - #Start again - self.timer = threading.Timer(30, self.run) - self.timer.start() + #Start again + self.timer = threading.Timer(30, self.run) + self.timer.start() - def cancel(self): - if self.running: - self.timer.cancel() - self.running = False + def cancel(self): + if self.running: + self.timer.cancel() + self.running = False class ConnectionError(Exception): - pass + pass class LoginError(Exception): - pass - + pass + class SignupError(Exception): - pass + pass Modified: trunk/client/core/parser.py =================================================================== --- trunk/client/core/parser.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/parser.py 2010-08-01 22:16:19 UTC (rev 351) @@ -16,146 +16,142 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Parser(): - def __init__(self, sh): - """ - This class parses all received messages from the server. - """ - self.sh = sh - self.call = sh['call'] - self.core = sh['core'] - - def __call__(self, msg): - self.call.data_received(msg) - - head = msg.keys()[0] - body = msg[head] - - func = getattr(self, str(head), None) - if (func): - func(body) - - def disconnect(self, msg): - """ - Called just before the server closes our connection. - * reason - Why the server disconnected us - "full" - Because the server is full - "duplicate" - Because another client has logged in - on the same account - "crash" - The server-parser has made a crash - "gone offline" - Server has just shutdown - """ - - self.core.close(msg["reason"]) - - def rsa(self, msg): - """ - Called when the connection has been made and a rsa-key has been - generated. We can now log in using this key - * public - The public rsa-key, which contains e & n - """ - - self.sh['rsakey'] = msg['public'] - - self.call.received_rsa(msg['public']) - - if self.core.cid == None and \ - self.sh['auto_login'] != (): - login = self.sh['auto_login'] - login[0](*login[1]) - - - def login(self, msg): - """ - Called when we can log in - * username - The username (with right caps) - * cid - The server's connection-id - * owner - The owner for this bot (only when logging in - as bot!) - """ - - if self.sh['isbot']: # Logging in as bot - self.core.owner = msg['owner'] - self.core.username = msg['username'] - self.core.cid = msg['cid'] - - self.call.logged_in(msg['username'], msg['cid'], - msg['owner']) - - else: # Logging in as user - self.core.username = msg['username'] - self.core.cid = msg['cid'] - - self.call.logged_in(msg['username'], msg['cid'], None) - - - def userlist(self, msg): - """ - Called after we've logged it. This contains a list with all - online users. This is a _list_ with: - * cid - The unique ID for this connection - * user - The username - * app - [Appname, Appversion] - * version - Which core it's using (string) - * bot - If it's a bot - * owner - The owner for this bot (only available when - bot = True) - * pos - [Z, X, Y] The position for this user. Is None - when you can't see this user. - """ - - # TODO - - pass - - def useronline(self, msg): - """ - Called after a user (or bot) has signed on. - * cid - The unique ID for this connection - * user - The username - * app - [Appname, Appversion] - * version - Which core it's using (string) - * bot - If it's a bot - * owner - The owner for this bot (only available when - bot = True) - * pos - [Z, X, Y] The position for this user. Is None - when you can't see this user. - """ - - # TODO - - pass - - def useroffline(self, msg): - """ - Some user has gone offline - * cid - The connection-id for this client - """ - - # TODO - - pass - - - def error(self, msg): - """ - Called when we did something wrong! - * reason - What we did wrong - "bad login" - Username/password wrong - "login not allowed" - User may not log in right now - "bot limit reached" - Too much bots logged in for this user - "login blocked" - The user (or IP) is blocked - "duplicate user" - There is already someone online with - this username - """ - - if msg['reason'] == "bad login": - self.call.failed_logging_in("bad login") - elif msg['reason'] == "login not allowed": - self.call.failed_logging_in("login not allowed") - elif msg['reason'] == "bot limit reached": - self.call.failed_logging_in("bot limit reached") - elif msg['reason'] == "login blocked": - self.call.failed_logging_in("login blocked") - elif msg['reason'] == "duplicate user": - self.call.failed_logging_in("duplicate user") - + def __init__(self, sh): + """ + This class parses all received messages from the server. + """ + self.sh = sh + self.call = sh['call'] + self.core = sh['core'] + + def __call__(self, msg): + self.call.data_received(msg) + + head = msg.keys()[0] + body = msg[head] + + func = getattr(self, str(head), None) + if (func): + func(body) + + def disconnect(self, msg): + """ + Called just before the server closes our connection. + * reason - Why the server disconnected us + "full - Because the server is full + "duplicate" - Because another client has logged in on the same + account + "crash" - The server-parser has made a crash + "gone offline"- Server has just shutdown + """ + + self.core.close(msg["reason"]) + + def rsa(self, msg): + """ + Called when the connection has been made and a rsa-key has been + generated. We can now log in using this key + * public - The public rsa-key, which contains e & n + """ + + self.sh['rsakey'] = msg['public'] + + self.call.received_rsa(msg['public']) + + if self.core.cid == None and self.sh['auto_login'] != (): + login = self.sh['auto_login'] + login[0](*login[1]) + + + def login(self, msg): + """ + Called when we can log in + * username - The username (with right caps) + * cid - The server's connection-id + * owner - The owner for this bot (only when logging in as bot!) + """ + + if self.sh['isbot']: # Logging in as bot + self.core.owner = msg['owner'] + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], msg['owner']) + + else: # Logging in as user + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], None) + + + def userlist(self, msg): + """ + Called after we've logged it. This contains a list with all + online users. This is a _list_ with: + * cid - The unique ID for this connection + * user - The username + * app - [Appname, Appversion] + * version - Which core it's using (string) + * bot - If it's a bot + * owner - The owner for this bot (only available when bot = True) + * pos - [Z, X, Y] The position for this user. Is None + when you can't see this user. + """ + + # TODO + + pass + + def useronline(self, msg): + """ + Called after a user (or bot) has signed on. + * cid - The unique ID for this connection + * user - The username + * app - [Appname, Appversion] + * version - Which core it's using (string) + * bot - If it's a bot + * owner - The owner for this bot (only available when + bot = True) + * pos - [Z, X, Y] The position for this user. Is None + when you can't see this user. + """ + + # TODO + + pass + + def useroffline(self, msg): + """ + Some user has gone offline + * cid - The connection-id for this client + """ + + # TODO + + pass + + + def error(self, msg): + """ + Called when we did something wrong! + * reason - What we did wrong + "bad login" - Username/password wrong + "login not allowed" - User may not log in right now + "bot limit reached" - Too much bots logged in for this user + "login blocked" - The user (or IP) is blocked + "duplicate user" - There is already someone online with this + username + """ + + if msg['reason'] == "bad login": + self.call.failed_logging_in("bad login") + elif msg['reason'] == "login not allowed": + self.call.failed_logging_in("login not allowed") + elif msg['reason'] == "bot limit reached": + self.call.failed_logging_in("bot limit reached") + elif msg['reason'] == "login blocked": + self.call.failed_logging_in("login blocked") + elif msg['reason'] == "duplicate user": + self.call.failed_logging_in("duplicate user") + Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/functions.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + import pygame, os, sys, threading from pygame.locals import * from hashlib import sha1 @@ -4,31 +21,33 @@ import core import gui + VERSION = "0.0.1" # This will be used to [sh]are all variables, functions and classes across the # code sh = {} + def real_path(*dir): - """ - Get the real path to this file - """ - return os.path.join(sys.path[0], *dir) + """ + Get the real path to this file + """ + return os.path.join(sys.path[0], *dir) def load_image(alpha, *dir): - """ - This will load an image for pygame - """ - - fullname = real_path(*dir) - try: - image = pygame.image.load(fullname) - if image.get_alpha is None or alpha == False: - image = image.convert() - else: - image = image.convert_alpha() - except pygame.error, message: - print 'Cannot load image:', fullname - raise SystemExit, message - return image + """ + This will load an image for pygame + """ + + fullname = real_path(*dir) + try: + image = pygame.image.load(fullname) + if image.get_alpha is None or alpha == False: + image = image.convert() + else: + image = image.convert_alpha() + except pygame.error, message: + print 'Cannot load image:', fullname + raise SystemExit, message + return image Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/gui.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * class Plane(): @@ -2,81 +19,78 @@ - def __init__(self, update, width, height): - self.update = update - self.width = width - self.height = height - self.surf = pygame.Surface((self.width, self.height), \ - SRCALPHA).convert_alpha() - self.norender = True - - self.childs = {} - - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - - def renderall(self): - self.norender = False - for child in self.childs.values(): - child.renderall(Rect(0,0,0,0), self.surf) - - self.update(Rect(0,0, self.width, self.height)) + def __init__(self, update, width, height): + self.update = update + self.width = width + self.height = height + self.surf = pygame.Surface((self.width, self.height), SRCALPHA) \ + .convert_alpha() + self.norender = True + + self.childs = {} + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self): + self.norender = False + for child in self.childs.values(): + child.renderall(Rect(0,0,0,0), self.surf) + + self.update(Rect(0,0, self.width, self.height)) - class Object(): - def __init__(self, name, rect): - self.name = name - self.rect = Rect(rect) - self.childs = {} - self.focus = False - self.hover = False - - # Load the defaults - self.__defaults__() + def __init__(self, name, rect): + self.name = name + self.rect = Rect(rect) + self.childs = {} + self.focus = False + self.hover = False + + # Load the defaults + self.__defaults__() - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - def renderall(self, correction, surf): - # First render ourself - self.render(correction, surf) - - # Then render our childs - for child in self.childs.values(): - child.renderall(correction.move(self.rect.topleft), surf) - + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self, correction, surf): + # First render ourself + self.render(correction, surf) + + # Then render our childs + for child in self.childs.values(): + child.renderall(correction.move(self.rect.topleft), surf) + - class Text(Object): - def __defaults__(self): - self.input = "" - self.cursorpos = 0 - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size - - surf.fill([255,0,0], pos) - - + def __defaults__(self): + self.input = "" + self.cursorpos = 0 + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([255,0,0], pos) + + class Button(Object): - def __defaults__(self): - self.caption = "" - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size - - surf.fill([0,0,255], pos) + def __defaults__(self): + self.caption = "" + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([0,0,255], pos) Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/layout.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * TOPBUTTONS = 3 @@ -4,105 +21,99 @@ TOPLEFT = 44 TOPBUTTONWIDTH = 304 TOPHEIGHT = 65 - + class Layout(): - - def __init__(self, sh): - self.sh = sh - - self.surf = pygame.Surface((1000, 700), \ - SRCALPHA).convert_alpha() - - self.status = None - - self.selected = None - self.hover = None - - # Login stuff - self.loginbg = None - self.loginfont = None - - # Playground stuff - self.topbar = None - - def event(self, ev): - if self.status == "playground": - if ev.type == MOUSEMOTION: - index = self.topbarcursor(ev.pos) - if index is not False: - if self.hover == index: return True - self.hover = index - self.updatetop() - - return True - else: - if self.hover == None: return - self.hover = None - self.updatetop() - - elif ev.type == ACTIVEEVENT: - if ev.state == 1: # Mouse events - if ev.gain == 0: # Lost mouse focus - if self.hover == None: return - self.hover = None - self.updatetop() - - elif ev.type == MOUSEBUTTONDOWN: - index = self.topbarcursor(ev.pos) - if index is False: return - - if self.selected == index: - self.selected = None - else: - self.selected = index - self.updatetop() - - return True - - - - - def changestatus(self, status): - login_list = ['connecting', 'login', 'logging in'] - if status in login_list and self.status not in login_list: - # (Un)load all the data - self.topbar = None - - elif status == "playground": - self.topbar = load_image(True, "images", "topbar.png") - - self.selected = None - self.hover = self.topbarcursor(pygame.mouse.get_pos()) - self.surf.blit(self.topbar, (0,0), (0,0,1000,TOPHEIGHT)) - self.updatetop() - - self.status = status - - - def updatetop(self): - for i in range(TOPBUTTONS): - left = TOPLEFT + (TOPBUTTONWIDTH*i) - rect = Rect(left, 0, TOPBUTTONWIDTH, TOPHEIGHT) - - self.surf.fill([0,0,0,0], rect) - - if self.selected is i: # This button is selected - rect2 = rect.move(0,TOPHEIGHT*2) - - elif self.hover is i: # This button is hovered - rect2 = rect.move(0,TOPHEIGHT) - - else: - rect2 = rect.move(0,0) - - self.surf.blit(self.topbar, rect, rect2) - - self.sh['update']((0,0, 1000, 65)) - - - def topbarcursor(self, pos): - if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ - and pos[1] < 55: - return (pos[0]-TOPLEFT) / TOPBUTTONWIDTH - else: - return False + + def __init__(self, sh): + self.sh = sh + + self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() + + self.status = None + + self.selected = None + self.hover = None + + # Login stuff + self.loginbg = None + self.loginfont = None + + # Playground stuff + self.topbar = None + + def event(self, ev): + if self.status == "playground": + if ev.type == MOUSEMOTION: + index = self.topbarcursor(ev.pos) + if index is not False: + if self.hover == index: return True + self.hover = index + self.updatetop() + + return True + else: + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse events + if ev.gain == 0: # Lost mouse focus + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == MOUSEBUTTONDOWN: + index = self.topbarcursor(ev.pos) + if index is False: return + + if self.selected == index: + self.selected = None + else: + self.selected = index + self.updatetop() + + return True + + def changestatus(... [truncated message content] |
From: <Blu...@us...> - 2010-08-01 21:27:20
|
Revision: 350 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=350&view=rev Author: BlueWolf_ Date: 2010-08-01 21:27:14 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Starting with the GUI-stuff. Hitting R when seeing the black box will result in a (fake) signup-request Modified Paths: -------------- trunk/client/VP.py trunk/client/core/client.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py Added Paths: ----------- trunk/client/gui.py trunk/client/images/loginbox.png Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/VP.py 2010-08-01 21:27:14 UTC (rev 350) @@ -71,6 +71,8 @@ print # Someone decided to close VP (Why??) + try: self.sh['client'].close() + except: pass sys.exit() Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/core/client.py 2010-08-01 21:27:14 UTC (rev 350) @@ -110,7 +110,7 @@ If you want to reconnect, you have to close the connection first, if it's still open. - You can to Client.login and Client.bot_login directly after + You can do Client.login and Client.bot_login directly after this. It will be done as soon as it has received a rsa-key. """ @@ -258,6 +258,28 @@ }) + def signup(self, usr, pwd, extra = {}): + """ + Create a new account with on the server. You should have a + connection first before using this. + """ + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + if self.cid != None: + raise SignupError("You are already logged in") + + + # Sign up + self.send("signup", { + "usr": usr, + "pwd": pwd, + "extra": extra + }) + + + def send(self, data_header, data_body = {}): """ Sends `data_body` of type `data_header` to the server. It will @@ -293,9 +315,11 @@ self.__do_connect.clear() # Block the thread-loop self.__sh['is_online'] = False - self.__pinger.cancel() - self.__pinger = None + if self.__pinger != None: + self.__pinger.cancel() + self.__pinger = None + # Reset variables self.__sh['rsakey'] = None self.username = None @@ -350,3 +374,6 @@ class LoginError(Exception): pass + +class SignupError(Exception): + pass Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/functions.py 2010-08-01 21:27:14 UTC (rev 350) @@ -1,6 +1,8 @@ import pygame, os, sys, threading from pygame.locals import * +from hashlib import sha1 import core +import gui VERSION = "0.0.1" Added: trunk/client/gui.py =================================================================== --- trunk/client/gui.py (rev 0) +++ trunk/client/gui.py 2010-08-01 21:27:14 UTC (rev 350) @@ -0,0 +1,84 @@ +from functions import * + +class Plane(): + + def __init__(self, update, width, height): + self.update = update + self.width = width + self.height = height + self.surf = pygame.Surface((self.width, self.height), \ + SRCALPHA).convert_alpha() + self.norender = True + + self.childs = {} + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + + def renderall(self): + self.norender = False + for child in self.childs.values(): + child.renderall(Rect(0,0,0,0), self.surf) + + self.update(Rect(0,0, self.width, self.height)) + + + +class Object(): + + def __init__(self, name, rect): + self.name = name + self.rect = Rect(rect) + self.childs = {} + self.focus = False + self.hover = False + + # Load the defaults + self.__defaults__() + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self, correction, surf): + # First render ourself + self.render(correction, surf) + + # Then render our childs + for child in self.childs.values(): + child.renderall(correction.move(self.rect.topleft), surf) + + + +class Text(Object): + + def __defaults__(self): + self.input = "" + self.cursorpos = 0 + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([255,0,0], pos) + + +class Button(Object): + + def __defaults__(self): + self.caption = "" + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([0,0,255], pos) + Added: trunk/client/images/loginbox.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/loginbox.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/layout.py 2010-08-01 21:27:14 UTC (rev 350) @@ -97,7 +97,7 @@ self.surf.blit(self.topbar, rect, rect2) - self.sh['update']() + self.sh['update']((0,0, 1000, 65)) def topbarcursor(self, pos): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/playground.py 2010-08-01 21:27:14 UTC (rev 350) @@ -12,7 +12,9 @@ # Login stuff self.loginbg = None + self.loginbox = None self.loginfont = None + self.logingui = None # Playground stuff # ... @@ -22,23 +24,34 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("test", "123") + self.sh['client'].login("test123", sha1("test123").hexdigest()) + + elif ev.type == KEYDOWN and ev.unicode == "r": + # Fake signup + self.sh['client'].signup("test123", sha1("test123").hexdigest(), { + "realname": "Pietje Precies", + "gender": "M" + }) def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] if status in login_list and self.status not in login_list: - # (Un)load all the data + # (Un)load all the data for the login self.loginbg = load_image(False, "images", \ "loginbg.png") + self.loginbox = load_image(True, "images", \ + "loginbox.png") self.loginfont = pygame.font.Font(real_path("fonts", \ "DejaVuSans.ttf"), 35) elif status == "playground": - # (Un)oad all the data + # (Un)load all the data for the playground self.loginbg = None + self.loginbox = None self.loginfont = None + self.logingui = None self.surf.fill([0,0,0]) self.sh['update']() @@ -66,11 +79,17 @@ self.surf.blit(text, (posleft, 330)) elif status == "login": - text = self.loginfont.render("Login-placeholder. " + \ - "Hit enter to fake log in", True, \ - (132,125,114)) - posleft = (1000/2)-(text.get_size()[0]/2) - self.surf.blit(text, (posleft, 330)) + self.surf.blit(self.loginbox, (292,256)) + # Create login-field + #self.logingui = gui.Plane(self.drawlogingui, 417,189) + #username = gui.Text("username", (0,0, 417, 50)) + #password = gui.Text("password", (0,50, 417, 50)) + #login = gui.Button("login", (0, 100, 417, 50)) + #self.logingui.add(username, password, login) + + # [TODO] Give mouseposition + #self.logingui.renderall() + elif status == "logging in": text = self.loginfont.render("Logging in...", True, \ @@ -79,3 +98,13 @@ self.surf.blit(text, (posleft, 330)) self.sh['update']() + + + def drawlogingui(self, rect): + rect_main = rect.move(292,256) + + self.surf.blit(self.loginbg, rect_main, rect_main) + self.surf.blit(self.loginbox, rect_main, rect) + self.surf.blit(self.logingui.surf, rect_main, rect) + + self.sh['update'](rect_main) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ch...@us...> - 2010-07-30 00:32:57
|
Revision: 349 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=349&view=rev Author: chozone Date: 2010-07-30 00:32:51 +0000 (Fri, 30 Jul 2010) Log Message: ----------- Another typo in server/callback.py, forgot 'print' for the actual string... woopsie... Modified Paths: -------------- trunk/server/callback.py Modified: trunk/server/callback.py =================================================================== --- trunk/server/callback.py 2010-07-30 00:22:33 UTC (rev 348) +++ trunk/server/callback.py 2010-07-30 00:32:51 UTC (rev 349) @@ -32,9 +32,9 @@ print "*** SERVER ONLINE ***" def enters_vp(self, cid): - " > %s"%cid + print " > %s"%cid def leaves_vp(self, cid): - " < %s"%cid + print " < %s"%cid def check_login(self, usr, pwd): db.execute("SELECT `username` FROM `users` WHERE \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ch...@us...> - 2010-07-30 00:22:39
|
Revision: 348 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=348&view=rev Author: chozone Date: 2010-07-30 00:22:33 +0000 (Fri, 30 Jul 2010) Log Message: ----------- typo in server/callback.py: (2nd)enters_vp -> leaves_vp Modified Paths: -------------- trunk/server/callback.py Modified: trunk/server/callback.py =================================================================== --- trunk/server/callback.py 2010-07-30 00:07:29 UTC (rev 347) +++ trunk/server/callback.py 2010-07-30 00:22:33 UTC (rev 348) @@ -33,7 +33,7 @@ def enters_vp(self, cid): " > %s"%cid - def enters_vp(self, cid): + def leaves_vp(self, cid): " < %s"%cid def check_login(self, usr, pwd): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ch...@us...> - 2010-07-30 00:07:35
|
Revision: 347 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=347&view=rev Author: chozone Date: 2010-07-30 00:07:29 +0000 (Fri, 30 Jul 2010) Log Message: ----------- [client] * Changed (fake login) user/pass to 'test'/'123' * Now connects with 'localhost' (temp!) [server] * Added base: * Loads config (asks user for values first time) * Opens database connection * Callback checks in database for logins [server-core] * Error corrections in comments * Modified code/comments for conversion to tabs with a width of 4 characters. * The server now uses select for it's main (listening) socket. socket.accept() blocks quite aggressively on Windows, making it impossible to close the server correctly. Using select fixes this. Modified Paths: -------------- trunk/client/VP.py trunk/client/playground.py trunk/server/core/callback.py trunk/server/core/functions.py trunk/server/core/parser.py trunk/server/core/server.py Added Paths: ----------- trunk/server/VPS.py trunk/server/callback.py trunk/server/database.py trunk/server/functions.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/client/VP.py 2010-07-30 00:07:29 UTC (rev 347) @@ -47,7 +47,7 @@ Callback(self.sh)) self.changestatus("connecting") - self.sh['client'].connect('vp.bluewolf.nl', 6653) + self.sh['client'].connect('localhost', 6653) # Wait for all the events to come Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/client/playground.py 2010-07-30 00:07:29 UTC (rev 347) @@ -22,7 +22,7 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("BlueWolf", "mypass") + self.sh['client'].login("test", "123") def changestatus(self, status): Added: trunk/server/VPS.py =================================================================== --- trunk/server/VPS.py (rev 0) +++ trunk/server/VPS.py 2010-07-30 00:07:29 UTC (rev 347) @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +## This file is part of Virtual Playground +## Copyright (c) 2009-2010 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import core +from functions import * +from callback import Callback + + +server = core.Server(config, Callback()) +server.start_server() + +# Now we sit back and let the server do it's stuff. Only stop at +# Keyboardinterrupts (^C). +# TODO: *some* interactivity here? (so you can type in commands) +try: + while 1: + time.sleep(100) + +except KeyboardInterrupt: + print + + +server.exit() +sys.exit() Added: trunk/server/callback.py =================================================================== --- trunk/server/callback.py (rev 0) +++ trunk/server/callback.py 2010-07-30 00:07:29 UTC (rev 347) @@ -0,0 +1,48 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009-2010 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +from core import Callback as BaseCallback + +from functions import * + +class Callback(BaseCallback): + def data_received(self, cid, data): + print " --> " + cid + ": " + repr(data) + def data_send(self, cid, data): + print " <-- " + cid + ": " + repr(data) + def debug_crash(self, traceback): + print "\n*** Crash ***\n\n%s\n" % traceback + + + def server_online(self, clients): + print "*** SERVER ONLINE ***" + + def enters_vp(self, cid): + " > %s"%cid + def enters_vp(self, cid): + " < %s"%cid + + def check_login(self, usr, pwd): + db.execute("SELECT `username` FROM `users` WHERE \ + `username`=%s AND \ + `password`=%s", (usr, pwd)) + print "* Login %s %s" % (usr, pwd) + result = db.fetchone() + if result is None: + return False + else: + return result['username'] \ No newline at end of file Modified: trunk/server/core/callback.py =================================================================== --- trunk/server/core/callback.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/server/core/callback.py 2010-07-30 00:07:29 UTC (rev 347) @@ -16,24 +16,31 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Callback: - def server_online(self): + def server_online(self, clients): """ Called when the server is online and ready to accept incoming - connections. This means it has successfully bounded itself to a - port. Most of the times this will be called immediately after - calling Server.start() + connections. This means it has successfully bounded itself to a port. + Most of the times this will be called immediately after calling + Server.start() + clients: + This is a dict where the server will store all the clients. The + server itself stores the socket-class and status of the user here. + However, you can add as much of your own data as you want, as long + as you don't overwrite any existing keys. So you probably want to + save a reference to this dict for easy user management. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass def connection_opened(self, cid, client, host, port): """ - Called when a new client connects and we accepted the - connection. You can, however, still kill the connection by - returning True in this function. + Called when a new client connects and we accepted the connection. + You can, however, still kill the connection by returning True in this + function. cid: The unique ID for this connection (connection-id). @@ -45,8 +52,8 @@ The current port for this connection. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass @@ -75,8 +82,8 @@ get the precise error - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass @@ -90,16 +97,15 @@ current_connections: Amount of current open connections max_connections: - This is the same as in the config - 'max_connections'. + This is the same as in the config 'max_connections'. host: The IP adress for this user. port: The current port for this connection. - This is placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass @@ -112,8 +118,8 @@ The unique ID for this connection (connection-id) - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass @@ -128,57 +134,57 @@ Dict with the data that will be send. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass - def debug_crash(self, tracback): + def debug_crash(self, traceback): """ - Usefull for debugging. Normally, when the parser (our any code - in the parser, like the callback) crashes, the connection will - be kicked and the error will be ignored. If you want to know the - precise error, use this function to get the trackback + Usefull for debugging. Normally, when the parser (or any code in the + parser, like the callback) crashes, the connection will be kicked and + the error will be ignored. If you want to know the precise error, use + this function to get the trackback traceback: A string... with a traceback, duh :-) - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ pass def check_login(self, usr, pwd): """ - This is used to verify the user's login. Return the real - username* when it's correct and False when it's not. This - function will return False by default. + This is used to verify the user's login. Return the real username* when + it's correct and False when it's not. This function will return False + by default. - * This is in case you decide to not make the username case - intensive. Now the clients knows the real username + * This is in case you decide to not make the username case sensetive. + Now the clients knows the real username. usr: The username pwd: The (double) sha-ed password - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ return False def may_login(self, username, screenname, ip, bot, bots): """ - This is called after (a succesfull) callback.check_login. Use - this to block certain users or IP's or block an additional bot - when the users reached the limit of connected bots. + This is called after (a succesfull) callback.check_login. Use this to + block certain users or IP's or block an additional bot when the users + reached the limit of connected bots. - Return True when the user (or bot) may log in and False when it - may not. This will send an "not allowed" error. If you wish to - send an other error, return the error. An example may be: + Return True when the user (or bot) may log in and False when it may not. + This will send an "not allowed" error. If you wish to send an other + error, return the error. An example may be: * "login not allowed" - Login is not allowed right now * "bot limit reached" - User has to much bots running * "login blocked" - User is blocked @@ -188,8 +194,8 @@ username: The username for this user / owner for this bot screenname: - The name the users see. This is only different from - username when a bot logs in + The name the users see. This is only different from username when a + bot logs in ip: The IP-adress this user has bot: @@ -198,8 +204,8 @@ List with the cids of all active active bots for this user. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback. + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ return True @@ -209,7 +215,12 @@ cid: The unique ID for this connection. (connection-id) + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ + pass def leaves_vp(self, cid): """ @@ -217,4 +228,9 @@ cid: The unique ID for this connection. (connection-id) + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback class. """ + pass Modified: trunk/server/core/functions.py =================================================================== --- trunk/server/core/functions.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/server/core/functions.py 2010-07-30 00:07:29 UTC (rev 347) @@ -24,20 +24,20 @@ Examples of some expression are: Exact match: - '1.0.3' match ONLY that version (True if version equal given) + '1.0.3' match ONLY that version (True if version equals given) Greater than: - '>0.9.48' match all versions above version '0.9.48', AND '0.9.48' - itself (True if same or above given) + '>0.9.48' match all versions above version '0.9.48', AND '0.9.48' itself + (True if same or above given) Lower than: - '<10.4.0' match all versions below version '10.4.0', AND '10.4.0' - itself (True if same or below given) + '<10.4.0' match all versions below version '10.4.0', AND '10.4.0' itself + (True if same or below given) Range: - '0.9.3-0.9.11' match all versions between '0.9.3' and '0.9.11', - including those values themselves (True if same or - between two values) + '0.9.3-0.9.11' match all versions between '0.9.3' and '0.9.11', including + those values themselves + (True if same or between two values) If all conditions are met, this function will return True, otherwise @@ -49,25 +49,25 @@ This is because it's not a decimal number. """ - # Filter out invalid versions/expressions, so this function works - # correctly later on. + # Filter out invalid versions/expressions, so this function works correctly + # later on. if not expr: return True if not version: return False version = str(version) expr = str(expr) try: [int(i) for i in version.split('.')] - except ValueError: raise ValueError, "No valid version: '%s'"%version + except ValueError: raise ValueError("No valid version: '%s'"%version) try: [[int(i) for i in p.split('.')] \ for p in expr.strip('<>').split('-')] - except ValueError: raise ValueError, "No valid expression: '%s'"%expr + except ValueError: raise ValueError("No valid expression: '%s'"%expr) # Our first real tests. If version matches expression, we return True. # Also, if the expression, stripped of '<' and '>' characters at the # beginning (or end...) matched our version, we return True. - # This is for the 'Greater/Lower OR EQUAL than' behaviour of those + # This is for the 'Greater/Lower OR EQUAL than' behaviour of those # characters. if version == expr: return True if version == expr.strip('<>'): return True @@ -83,10 +83,9 @@ c1 = [int(i) for i in version.split('.')] c2 = [int(i) for i in expr.split('.')] - # Loops through major, minor, revision, in that order, and - # it tests whether the version is higher/lower. Note that if the - # version are the same, it has already been filtered out, before - # this if block. + # Loops through major, minor, revision, in that order, and it tests + # whether the version is higher/lower. Note that if the version are the + # same, it has already been filtered out, before this if block. for p1, p2 in zip(c1, c2): if p1 > p2: return True if p1 < p2: return False @@ -103,10 +102,9 @@ c1 = [int(i) for i in version.split('.')] c2 = [int(i) for i in expr.split('.')] - # Loops through major, minor, revision, in that order, and - # it tests whether the version is higher/lower. Note that if the - # version are the same, it has already been filtered out, before - # this if block. + # Loops through major, minor, revision, in that order, and it tests + # whether the version is higher/lower. Note that if the version are the + # same, it has already been filtered out, before this if block. for p1, p2 in zip(c1, c2): if p1 < p2: return True if p1 > p2: return False @@ -116,8 +114,8 @@ # Get the two versions r1, r2 = expr.split('-') - # Use this function to see if it's higher than the first, and - # lower than the second value :-) + # Use this function to see if it's higher than the first, and lower + # than the second value :-) if check_version(version, '>' + r1) \ and check_version(version, '<' + r2): return True Modified: trunk/server/core/parser.py =================================================================== --- trunk/server/core/parser.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/server/core/parser.py 2010-07-30 00:07:29 UTC (rev 347) @@ -163,13 +163,11 @@ # Check for double logins if msg['bot'] == False: # Just an ordinary user - if self._check_double_user(False, username, - data) == False: + if self._check_double_user(False, username, data) == False: return else: # Client is a bot - if self._check_double_user(True, screenname, - data) == False: + if self._check_double_user(True, screenname, data) == False: return Modified: trunk/server/core/server.py =================================================================== --- trunk/server/core/server.py 2010-07-29 22:04:01 UTC (rev 346) +++ trunk/server/core/server.py 2010-07-30 00:07:29 UTC (rev 347) @@ -15,7 +15,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import simplejson, socket, threading, time, random, sys, hashlib +import simplejson, socket, threading, time, random, sys, hashlib, select from functions import * from parser import Parser @@ -30,9 +30,8 @@ config: - This should be a dict with settings for the server. See the - bottom of this documentation for a list of all possible - settings. + This should be a dict with settings for the server. See the bottom of + this documentation for a list of all possible settings. callback_class: The callback class will be used to notify you for certain events @@ -47,22 +46,21 @@ The settings: -host: - Host to which the server binds itself. The default is an - empty string, an empty string, which means everyone can - connect to the server. + Host to which the server binds itself. The default is an empty + string, an empty string, which means everyone can connect + to the server. -port: - The port the server should listen on. Should be int - between 1 and 65535. Note that everything lower than 100 - usually needs to be run as root under Unix/Linux. + The port the server should listen on. Should be int between + 1 and 65535. Note that everything lower than 100 usually needs to + be run as root under Unix/Linux. Default is 5162. -max_connections: - Maximum amount of clients that can be connected - simultaneously. If this number is exceeded, the new - connection will dropped, unless specified otherwise - (see callback `connection_limit_exceeded`). Should be - int. If this value is either None or 0, there will be no + Maximum amount of clients that can be connected simultaneously. + If this number is exceeded, the new connection will dropped, unless + specified otherwise (see callback `connection_limit_exceeded`). + Should be int. If this value is either None or 0, there will be no limit. Default is 0. But it is wise to specify a limit. -rsa_bits: @@ -70,23 +68,21 @@ More = more secure but slower to generate. Default is 64 -bot_names: - How the name for a bot should be. Use %s where the - suggested name should be. Default is [%s]. When a bot - logs in as "test", it will be displayed as "[test]". - Choose something that won't interfere with existing - users. + How the name for a bot should be. Use %s where the suggested name + should be. Default is [%s]. When a bot logs in as "test", it will + be displayed as "[test]". Choose something that won't interfere + with existing users. -viewport: - A tuple of the client's viewport in pixels. This is very - important because it's used to calculate which objects - and people the client is able to see. By default this - is (1000, 700). + A tuple of the client's viewport in pixels. This is very important + because it's used to calculate which objects and people the client + is able to see. By default this is (1000, 700). -max_speed: The amount of pixels a user may move in a certain time. - The default is (50, 1.0) which basically means 50px per - 1 second. When a user exceeds this, the server will just - reset his position to his last known location. + The default is (50, 1.0) which basically means 50px per 1 second. + When a user exceeds this, the server will just reset his position + to his last known location. """ @@ -130,16 +126,14 @@ in the config. """ - #Isn't the server running already? + # Isn't the server running already? if self.__sock: raise ConnectionError("The server is already online!") - #Load our server socket - self.__sock = socket.socket(socket.AF_INET, - socket.SOCK_STREAM) - #Configure it to re-use the previous one - self.__sock.setsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR, 1) + # Load our server socket + self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # Configure it to re-use the previous one + self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.start() #For more adventures of the socket, see `run` @@ -149,11 +143,11 @@ Used by threading, not for external usage. """ - #Try to claim the pre-specified port + # Try to claim the pre-specified port while 1: try: self.__sock.bind((self.__sh['config']['host'], - self.__sh['config']['port'])) + self.__sh['config']['port'])) break except: time.sleep(1) @@ -161,25 +155,31 @@ self.__sock.listen(20) self.__call.server_online(self.clients) - #Infinite loop that will wait for incomming connections - while 1: - try: sock, addr = self.__sock.accept() - except: + # Infinite loop that will wait for incomming connections + while 1: + r,w,e = select.select([self.__sock], [], [], 10) + + if not r: + # No new clients trying to connect, better luck next time + continue + if not self.__sock: # Server has gone offline return + sock, addr = r[0].accept() + + if self.__sh['config']['max_connections'] and \ - len(self.clients) >= \ - self.__sh['config']['max_connections']: - #We exceeded our connection limit, but maybe - #this is a special occasion? Send callback! + len(self.clients) >= self.__sh['config']['max_connections']: + # We exceeded our connection limit, but maybe this is a special + # occasion? Send callback! if not self.__call.connection_limit_exceeded( - len(self.clients), - self.__sh['config']['max_connections'], - addr[0], addr[1]): + len(self.clients), + self.__sh['config']['max_connections'], + addr[0], addr[1]): - #We're full, kick him out - #Tell him we're full + # We're full, kick him out + # Tell him we're full data = simplejson.dumps({ "disconnect":{"reason":"full"} }) @@ -192,18 +192,16 @@ # Create unique client-id cid = hashlib.sha1(addr[0] + str(addr[1])).hexdigest()[:8] while cid in self.clients: - cid = hashlib.sha1(addr[0] + str(addr[1]) + - str(random.random())).hexdigest()[:8] + cid = hashlib.sha1(addr[0] + str(addr[1]) + + str(random.random())).hexdigest()[:8] self.clients[cid] = { "status": "", - "con": Client(cid, sock, self.__sh, - self.__parse) + "con": Client(cid, sock, self.__sh, self.__parse) } - if self.__call.connection_opened(cid, - self.clients[cid], *addr): - #User returned True -> drop user + if self.__call.connection_opened(cid, self.clients[cid], *addr): + # User returned True -> drop user self.clients[cid]['con'].close() continue @@ -211,9 +209,9 @@ def exit(self, reason = "gone offline"): """ - Will shutdown the server and sends an 'gone offline' message to - all connected clients and then closes their connection. Use this - when you're about to shutdown your server. + Will shutdown the server and sends an 'gone offline' message to all + connected clients and then closes their connection. Use this when + you're about to shutdown your server. This will call the callback.connection_closed for all clients! Note that you'll not be able to start the server again @@ -225,6 +223,7 @@ for client in self.clients.values(): client['con'].close_msg(reason) + @@ -255,13 +254,12 @@ Will create a traceback and call the callback """ - #Get some debugging info + # Get some debugging info et, ev, tb = sys.exc_info() traceback = "" while tb: co = tb.tb_frame.f_code - traceback += str(co.co_filename) + ':' + \ - str(tb.tb_lineno) + '\n' + traceback += str(co.co_filename) + ':' + str(tb.tb_lineno) + '\n' tb = tb.tb_next traceback += ev.__class__.__name__ + ': ' + str(ev) @@ -294,19 +292,18 @@ Used by threading, not for external usage. """ - #Client must ping (at least) every 30 seconds. So we set a - #timeout of 45 seconds. + # Client must ping (at least) every 30 seconds. So we set a + # timeout of 45 seconds. self.__sock.settimeout(45) - # Before the client can log in, we first need to create a - # rsa-key + # Before the client can log in, we first need to create a rsa-key public, private = rsa.gen_pubpriv_keys( self.__sh['config']['rsa_bits']) self.__clients[self.__cid]['rsa'] = private self.send("rsa", {"public": public}) - #Infinite loop that receives data + # Infinite loop that receives data buffer = '' while 1: try: @@ -322,7 +319,7 @@ return buffer += data - #Each dataset must end with a delimiter: chr(1) + # Each dataset must end with a delimiter: chr(1) if chr(1) in buffer: data = buffer.split(chr(1)) buffer = data[-1] @@ -330,8 +327,7 @@ for msg in data: try: - self.__parser(self.__cid, - simplejson.loads(msg)) + self.__parser(self.__cid, simplejson.loads(msg)) except Exception, Er: self.__parser_crash() @@ -362,8 +358,8 @@ def close_msg(self, reason): """ - Same as Client.close, but this will send the reason to the - client before closing + Same as Client.close, but this will send the reason to the client + before closing. """ if self.is_online == False: return @@ -385,8 +381,8 @@ def send(self, data_header, data_body = {}): """ Sends `data_body` of type `data_header` to the client. It will - automatically be encoded as JSON, and the delimeter character - (chr(1)) will be send automatically too. + automatically be encoded as JSON, and the delimeter character (chr(1)) + will be send automatically too. `data_header` is a string, `data_body` a dict. """ self.__call.data_send(self.__cid, {data_header:data_body}) Added: trunk/server/database.py =================================================================== --- trunk/server/database.py (rev 0) +++ trunk/server/database.py 2010-07-30 00:07:29 UTC (rev 347) @@ -0,0 +1,83 @@ +## Copyright (c) 2009 Koen Koning + Thomas van Ophem + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +import sys + +try: import MySQLdb +except: sys.exit("ERROR: You need the MySQLdb-module for this to work!") + +class DB(): + #Let's initialize the database + def __init__(self, host, database, user, passwd): + self.host = host + self.database = database + self.user = user + self.passwd = passwd + + self._connect() + + #Let's connect to the database.. + def _connect(self): + try: + self.dbcon = MySQLdb.Connect( + host=self.host, + user=self.user, + passwd=self.passwd, + db = self.database) + self.db = self.dbcon.cursor(MySQLdb.cursors.DictCursor) + except: + #sys.exit("Could not connect to the database!") + raise self.DBConnectionError("Could not connect to the database!") + + def __getattr__(self, attr): + """ + Called when function is not here in our class. + We pass everything through to our MySQLdb + """ + def exc (*arg): + """ + Will return the real function, from MySQLdb. + Will ping before every command, + so it will automatically reconnect. + """ + + # Uncomment for mysql-debugging! + #print '\tMySQLdb.' + attr + repr(arg) + + func = getattr(self.db, attr) + try: + dbfunc = func(*arg) + except MySQLdb.OperationalError, message: + if message[0] == 2006: #Mysql has gone away + self._connect() + func = getattr(self.db, attr) + dbfunc = func(*arg) + else: #Some other error we don't care about + raise MySQLdb.OperationalError, message + + return dbfunc + + return exc + + + + class DBConnectionError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + Added: trunk/server/functions.py =================================================================== --- trunk/server/functions.py (rev 0) +++ trunk/server/functions.py 2010-07-30 00:07:29 UTC (rev 347) @@ -0,0 +1,71 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009-2010 Jos Ratsma + Koen Koning + +## 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, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import os, sys, time + +import database + +try: from configobj import ConfigObj +except: sys.exit("ERROR: You need the configobj-module for this to work!") + +def config_defaults(config): + if 'database' not in config: + config['database'] = {} + + intro_text = """ +Some settings are missing from the config. Because these settings are required, +We will now ask for them in this console. Please type in the correct value, and +press enter. It will be automatically written to the config. +""" + + if not 'host' in config['database']: + if intro_text: + print intro_text + intro_text = None + config['database']['host'] = raw_input("Database host: ") + if not 'database' in config['database']: + if intro_text: + print intro_text + intro_text = None + config['database']['database'] = raw_input("Database name: ") + if not 'user' in config['database']: + if intro_text: + print intro_text + intro_text = None + config['database']['user'] = raw_input("Database user: ") + if not 'password' in config['database']: + if intro_text: + print intro_text + intro_text = None + config['database']['password'] = raw_input("Database password: ") + + + +config = ConfigObj(os.path.join(sys.path[0], 'config')) +config_defaults(config) +config.write() + +print "Connecting to database..." +db = database.DB( config['database']['host'], + config['database']['database'], + config['database']['user'], + config['database']['password']) +print "Connected to database `%s` on `%s`" % (config['database']['database'], + config['database']['host']) + + + \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-29 22:04:08
|
Revision: 346 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=346&view=rev Author: BlueWolf_ Date: 2010-07-29 22:04:01 +0000 (Thu, 29 Jul 2010) Log Message: ----------- I maaaaaay've forgotten a little thing to add. Which happens to be really important.. kinda.. Added Paths: ----------- trunk/client/images/topbar.png Removed Paths: ------------- trunk/client/images/topbar1.png trunk/client/images/topbar2.png trunk/client/images/topbar3.png Added: trunk/client/images/topbar.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: trunk/client/images/topbar1.png =================================================================== (Binary files differ) Deleted: trunk/client/images/topbar2.png =================================================================== (Binary files differ) Deleted: trunk/client/images/topbar3.png =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 23:02:18
|
Revision: 345 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=345&view=rev Author: BlueWolf_ Date: 2010-07-28 23:02:12 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Topbar looks now good. You can now click on them (nothing happens, only the image will change) and merged the 3 states into a single image Modified Paths: -------------- trunk/client/images/topbar1.png trunk/client/images/topbar2.png trunk/client/images/topbar3.png trunk/client/layout.py Modified: trunk/client/images/topbar1.png =================================================================== (Binary files differ) Modified: trunk/client/images/topbar2.png =================================================================== (Binary files differ) Modified: trunk/client/images/topbar3.png =================================================================== (Binary files differ) Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 22:53:36 UTC (rev 344) +++ trunk/client/layout.py 2010-07-28 23:02:12 UTC (rev 345) @@ -28,12 +28,8 @@ def event(self, ev): if self.status == "playground": if ev.type == MOUSEMOTION: - if ev.pos[0] > 44 and ev.pos[0] < 926 and \ - ev.pos[1] < 55: - - index = (ev.pos[0]-TOPLEFT)/ \ - TOPBUTTONWIDTH - + index = self.topbarcursor(ev.pos) + if index is not False: if self.hover == index: return True self.hover = index self.updatetop() @@ -43,7 +39,26 @@ if self.hover == None: return self.hover = None self.updatetop() + + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse events + if ev.gain == 0: # Lost mouse focus + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == MOUSEBUTTONDOWN: + index = self.topbarcursor(ev.pos) + if index is False: return + + if self.selected == index: + self.selected = None + else: + self.selected = index + self.updatetop() + return True + @@ -54,15 +69,11 @@ self.topbar = None elif status == "playground": - self.topbar = [ - load_image(True, "images", "topbar1.png"), - load_image(True, "images", "topbar2.png"), - load_image(True, "images", "topbar3.png") - ] + self.topbar = load_image(True, "images", "topbar.png") self.selected = None - self.hover = None # [TODO] This can be better - self.surf.blit(self.topbar[0], (0,0)) + self.hover = self.topbarcursor(pygame.mouse.get_pos()) + self.surf.blit(self.topbar, (0,0), (0,0,1000,TOPHEIGHT)) self.updatetop() self.status = status @@ -71,17 +82,27 @@ def updatetop(self): for i in range(TOPBUTTONS): left = TOPLEFT + (TOPBUTTONWIDTH*i) - rect = (left, 0, TOPBUTTONWIDTH, TOPHEIGHT) + rect = Rect(left, 0, TOPBUTTONWIDTH, TOPHEIGHT) self.surf.fill([0,0,0,0], rect) - if self.selected == i: # This button is selected - self.surf.blit(self.topbar[2], rect, rect) + if self.selected is i: # This button is selected + rect2 = rect.move(0,TOPHEIGHT*2) - elif self.hover == i: # This button is hovered - self.surf.blit(self.topbar[1], rect, rect) + elif self.hover is i: # This button is hovered + rect2 = rect.move(0,TOPHEIGHT) else: - self.surf.blit(self.topbar[0], rect, rect) + rect2 = rect.move(0,0) + + self.surf.blit(self.topbar, rect, rect2) self.sh['update']() + + + def topbarcursor(self, pos): + if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ + and pos[1] < 55: + return (pos[0]-TOPLEFT) / TOPBUTTONWIDTH + else: + return False This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 22:53:42
|
Revision: 344 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=344&view=rev Author: BlueWolf_ Date: 2010-07-28 22:53:36 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Fixed the weird alligned button (and added the forgotten-to-add background thingy stuff) Modified Paths: -------------- res/images/xcf/bar-click.xcf res/images/xcf/bar-hover.xcf res/images/xcf/bar.xcf Added Paths: ----------- res/images/xcf/loginbg.xcf Modified: res/images/xcf/bar-click.xcf =================================================================== (Binary files differ) Modified: res/images/xcf/bar-hover.xcf =================================================================== (Binary files differ) Modified: res/images/xcf/bar.xcf =================================================================== (Binary files differ) Added: res/images/xcf/loginbg.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/loginbg.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 20:51:53
|
Revision: 343 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=343&view=rev Author: BlueWolf_ Date: 2010-07-28 20:51:47 +0000 (Wed, 28 Jul 2010) Log Message: ----------- The topnav reacts to hovers. And then I discovered the image isn't perfect symmetric, hence the weird block box that appears next to the right button. grr.. Modified Paths: -------------- trunk/client/layout.py trunk/client/playground.py Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 19:19:04 UTC (rev 342) +++ trunk/client/layout.py 2010-07-28 20:51:47 UTC (rev 343) @@ -1,6 +1,12 @@ from functions import * +TOPBUTTONS = 3 +TOPLEFT = 44 +TOPBUTTONWIDTH = 304 +TOPHEIGHT = 65 + class Layout(): + def __init__(self, sh): self.sh = sh @@ -9,6 +15,9 @@ self.status = None + self.selected = None + self.hover = None + # Login stuff self.loginbg = None self.loginfont = None @@ -17,9 +26,27 @@ self.topbar = None def event(self, ev): - pass + if self.status == "playground": + if ev.type == MOUSEMOTION: + if ev.pos[0] > 44 and ev.pos[0] < 926 and \ + ev.pos[1] < 55: + + index = (ev.pos[0]-TOPLEFT)/ \ + TOPBUTTONWIDTH + + if self.hover == index: return True + self.hover = index + self.updatetop() + + return True + else: + if self.hover == None: return + self.hover = None + self.updatetop() + + def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] if status in login_list and self.status not in login_list: @@ -33,6 +60,28 @@ load_image(True, "images", "topbar3.png") ] + self.selected = None + self.hover = None # [TODO] This can be better self.surf.blit(self.topbar[0], (0,0)) - - self.sh['update']() + self.updatetop() + + self.status = status + + + def updatetop(self): + for i in range(TOPBUTTONS): + left = TOPLEFT + (TOPBUTTONWIDTH*i) + rect = (left, 0, TOPBUTTONWIDTH, TOPHEIGHT) + + self.surf.fill([0,0,0,0], rect) + + if self.selected == i: # This button is selected + self.surf.blit(self.topbar[2], rect, rect) + + elif self.hover == i: # This button is hovered + self.surf.blit(self.topbar[1], rect, rect) + + else: + self.surf.blit(self.topbar[0], rect, rect) + + self.sh['update']() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 19:19:04 UTC (rev 342) +++ trunk/client/playground.py 2010-07-28 20:51:47 UTC (rev 343) @@ -22,7 +22,7 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("myname", "mypass") + self.sh['client'].login("BlueWolf", "mypass") def changestatus(self, status): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 19:19:10
|
Revision: 342 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=342&view=rev Author: BlueWolf_ Date: 2010-07-28 19:19:04 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Made a really fast (fake) login. But it will connect and login with the server now! Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added Paths: ----------- trunk/client/fonts/ trunk/client/fonts/DejaVuSans-Bold.ttf trunk/client/fonts/DejaVuSans.ttf Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/VP.py 2010-07-28 19:19:04 UTC (rev 342) @@ -2,6 +2,8 @@ from functions import * +import core + from playground import Playground from layout import Layout from windows import Windows @@ -9,30 +11,43 @@ class Main(): def __init__(self): - self.blit_lock = threading.Lock() + self.sh = {} # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' pygame.init() pygame.display.set_caption('Virtual Playground') - sh['screen'] = pygame.display.set_mode((1000, 700)) + self.sh['screen'] = pygame.display.set_mode((1000, 700)) #icon = load_image('img','icon.png') #pygame.display.set_icon(icon) pygame.key.set_repeat(250, 40) pygame.scrap.init() - + self.clock = pygame.time.Clock() + + self.sh['main'] = self + # Give the surfaces a way to blit itself - sh['update'] = self.update + self.sh['update'] = self.update + self.updaterect = [] + self.updatewaiting = False - sh['status'] = "login" # What the user is seeing - # login - playground # Create all our surfaces - sh['playground'] = Playground() - sh['layout'] = Layout() - sh['windows'] = Windows() + self.sh['playground'] = Playground(self.sh) + self.sh['layout'] = Layout(self.sh) + self.sh['windows'] = Windows(self.sh) self.update() + + + # Connect to the server + self.sh['client'] = core.Client({ + 'app_name': "Virtual Playground", + 'app_version': VERSION}, + Callback(self.sh)) + + self.changestatus("connecting") + self.sh['client'].connect('vp.bluewolf.nl', 6653) # Wait for all the events to come @@ -47,9 +62,9 @@ pygame.event.clear(MOUSEMOTION) # Send through all the layers - if sh['windows'].event(ev): continue - if sh['layout'].event(ev): continue - if sh['playground'].event(ev): continue + if self.sh['windows'].event(ev): continue + if self.sh['layout'].event(ev): continue + if self.sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly @@ -66,15 +81,65 @@ and update the screen """ - # Prevent multiple threads from blitting at the same time - self.blit_lock.acquire() + # The following code will prevent it from going crazy on the cpu + # aka: using unlimited FPS. This will limit the FPS to 50 and + # will remember everything that should be updated in the mean + # time - sh['screen'].blit(sh['playground'].surf, rect, rect) - sh['screen'].blit(sh['layout'].surf, rect, rect) - sh['screen'].blit(sh['windows'].surf, rect, rect) + self.updaterect.append(rect) + if self.updatewaiting: + # Rect is saved. Will be updated once self.clock stops + # blocking + return + # When there are more updates from here one, they will be saved + # without being updated immediately. We will do that once tick + # stops blocking + self.updatewaiting = True + self.clock.tick(50) + + # Get all the rects to update + if len(self.updaterect) == 1: + rects = self.updaterect[0] + else: + rects = self.updaterect[0].unionall(self.updaterect[1:]) + + self.updaterect = [] + self.updatewaiting = False + + + # The actual updating happens here + self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) + self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) + self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + pygame.display.update(rect) + + def changestatus(self, status): + self.sh['playground'].changestatus(status) + self.sh['layout'].changestatus(status) + self.sh['windows'].changestatus(status) + + +class Callback(core.Callback): + def __init__(self, sh): + self.sh = sh - self.blit_lock.release() + def data_received(self, data): + print " --> " + repr(data) + + def data_send(self, data): + print " <-- " + repr(data) + + def disconnect(self, reason): + print "Server disconnected: " + reason + + def received_rsa(self, public): + # We are connected + self.sh['main'].changestatus("login") + + def logged_in(self, username, cid, owner): + self.sh['main'].changestatus("playground") + if __name__ == "__main__": Main() Added: trunk/client/fonts/DejaVuSans-Bold.ttf =================================================================== (Binary files differ) Property changes on: trunk/client/fonts/DejaVuSans-Bold.ttf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/fonts/DejaVuSans.ttf =================================================================== (Binary files differ) Property changes on: trunk/client/fonts/DejaVuSans.ttf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/functions.py 2010-07-28 19:19:04 UTC (rev 342) @@ -2,6 +2,8 @@ from pygame.locals import * import core +VERSION = "0.0.1" + # This will be used to [sh]are all variables, functions and classes across the # code sh = {} Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/layout.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,9 +1,38 @@ from functions import * class Layout(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() + self.status = None + + # Login stuff + self.loginbg = None + self.loginfont = None + + # Playground stuff + self.topbar = None + def event(self, ev): pass + + + def changestatus(self, status): + login_list = ['connecting', 'login', 'logging in'] + if status in login_list and self.status not in login_list: + # (Un)load all the data + self.topbar = None + + elif status == "playground": + self.topbar = [ + load_image(True, "images", "topbar1.png"), + load_image(True, "images", "topbar2.png"), + load_image(True, "images", "topbar3.png") + ] + + self.surf.blit(self.topbar[0], (0,0)) + + self.sh['update']() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/playground.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,18 +1,81 @@ from functions import * class Playground(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) + self.status = None + # Login stuff self.loginbg = None - self.drawlogin() + self.loginfont = None + + # Playground stuff + # ... def event(self, ev): - print ev + if self.status == "login": + if ev.type == KEYDOWN and ev.unicode == "\r": + # Fake login + self.drawlogin("logging in") + self.sh['client'].login("myname", "mypass") + - def drawlogin(self): - self.loginbg = load_image(False, "images", "loginbg.png") + def changestatus(self, status): + login_list = ['connecting', 'login', 'logging in'] + if status in login_list and self.status not in login_list: + # (Un)load all the data + self.loginbg = load_image(False, "images", \ + "loginbg.png") + self.loginfont = pygame.font.Font(real_path("fonts", \ + "DejaVuSans.ttf"), 35) + + + elif status == "playground": + # (Un)oad all the data + self.loginbg = None + self.loginfont = None + + self.surf.fill([0,0,0]) + self.sh['update']() + + + if status == "connecting": + self.drawlogin("connecting") + elif status == "login": + self.drawlogin("login") + elif status == "logging in": + self.drawlogin("logging in") + + self.status = status + + + def drawlogin(self, status): + self.loginstatus = status self.surf.blit(self.loginbg, (0,0)) + + if status == "connecting": + + text = self.loginfont.render("Connecting...", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + elif status == "login": + text = self.loginfont.render("Login-placeholder. " + \ + "Hit enter to fake log in", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + elif status == "logging in": + text = self.loginfont.render("Logging in...", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + self.sh['update']() Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/windows.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,9 +1,14 @@ from functions import * class Windows(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() def event(self, ev): pass + + def changestatus(self, status): + pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 16:06:53
|
Revision: 341 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=341&view=rev Author: BlueWolf_ Date: 2010-07-28 16:06:43 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Starting with the interface here as well! :D Modified Paths: -------------- trunk/client/VP.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added Paths: ----------- trunk/client/images/ trunk/client/images/loginbg.png trunk/client/images/topbar1.png trunk/client/images/topbar2.png trunk/client/images/topbar3.png Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/VP.py 2010-07-28 16:06:43 UTC (rev 341) @@ -21,8 +21,11 @@ pygame.key.set_repeat(250, 40) pygame.scrap.init() - # Give the surfaces a way to blit themselves + # Give the surfaces a way to blit itself sh['update'] = self.update + + sh['status'] = "login" # What the user is seeing + # login - playground # Create all our surfaces sh['playground'] = Playground() @@ -43,7 +46,10 @@ pos = pygame.mouse.get_pos() pygame.event.clear(MOUSEMOTION) - # [TODO] Do something + # Send through all the layers + if sh['windows'].event(ev): continue + if sh['layout'].event(ev): continue + if sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly @@ -60,8 +66,7 @@ and update the screen """ - # Prevent multiple threads blitting at - # the same time + # Prevent multiple threads from blitting at the same time self.blit_lock.acquire() sh['screen'].blit(sh['playground'].surf, rect, rect) Added: trunk/client/images/loginbg.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/loginbg.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar1.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar1.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar2.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar2.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar3.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/layout.py 2010-07-28 16:06:43 UTC (rev 341) @@ -5,4 +5,5 @@ self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() - self.surf.fill([0,100,0], Rect(100,100, 150,150)) + def event(self, ev): + pass Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/playground.py 2010-07-28 16:06:43 UTC (rev 341) @@ -6,3 +6,13 @@ SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) + + self.loginbg = None + self.drawlogin() + + def event(self, ev): + print ev + + def drawlogin(self): + self.loginbg = load_image(False, "images", "loginbg.png") + self.surf.blit(self.loginbg, (0,0)) Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/windows.py 2010-07-28 16:06:43 UTC (rev 341) @@ -4,3 +4,6 @@ def __init__(self): self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() + + def event(self, ev): + pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 15:37:11
|
Revision: 340 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=340&view=rev Author: BlueWolf_ Date: 2010-07-28 15:37:05 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Starting with the layout Added Paths: ----------- res/images/xcf/bar-click.xcf res/images/xcf/bar-hover.xcf res/images/xcf/bar.xcf Removed Paths: ------------- res/images/xcf/login.background.xcf Added: res/images/xcf/bar-click.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/bar-click.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: res/images/xcf/bar-hover.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/bar-hover.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: res/images/xcf/bar.xcf =================================================================== (Binary files differ) Property changes on: res/images/xcf/bar.xcf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: res/images/xcf/login.background.xcf =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-27 19:28:01
|
Revision: 339 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=339&view=rev Author: BlueWolf_ Date: 2010-07-27 19:27:54 +0000 (Tue, 27 Jul 2010) Log Message: ----------- Added a max speed option in the config. Does -of course- nothing right now. It's just there for the decoration :D Modified Paths: -------------- trunk/server/core/functions.py trunk/server/core/server.py Modified: trunk/server/core/functions.py =================================================================== --- trunk/server/core/functions.py 2010-04-24 22:05:37 UTC (rev 338) +++ trunk/server/core/functions.py 2010-07-27 19:27:54 UTC (rev 339) @@ -15,7 +15,6 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - def check_version(version, expr): """ Checks whether a version meets certain conditions. Modified: trunk/server/core/server.py =================================================================== --- trunk/server/core/server.py 2010-04-24 22:05:37 UTC (rev 338) +++ trunk/server/core/server.py 2010-07-27 19:27:54 UTC (rev 339) @@ -69,18 +69,24 @@ How many bits the rsa uses for encrypting the password. More = more secure but slower to generate. Default is 64 - -bot_names + -bot_names: How the name for a bot should be. Use %s where the suggested name should be. Default is [%s]. When a bot logs in as "test", it will be displayed as "[test]". Choose something that won't interfere with existing users. - -viewport + -viewport: A tuple of the client's viewport in pixels. This is very important because it's used to calculate which objects - and people the client is able to see. By default, this + and people the client is able to see. By default this is (1000, 700). + + -max_speed: + The amount of pixels a user may move in a certain time. + The default is (50, 1.0) which basically means 50px per + 1 second. When a user exceeds this, the server will just + reset his position to his last known location. """ @@ -115,6 +121,8 @@ config['bot_names'] = str(config.get('bot_names', "[%s]")) config['viewport'] = tuple(config.get('viewport', (1000,700))) + config['max_speed'] = tuple(config.get('max_speed', (50, 1.0))) + def start_server(self): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |