Mercurial > traipse_dev
comparison orpg/networking/mplay_server.py @ 56:c7f04d3c76f5 traipse_dev
Major update to Server GUI. Basically makes it functional.
author | sirebral |
---|---|
date | Fri, 07 Aug 2009 21:53:14 -0500 |
parents | 4385a7d0efd1 |
children | 9014d7861bb3 |
comparison
equal
deleted
inserted
replaced
55:0b79d5dbbe9e | 56:c7f04d3c76f5 |
---|---|
365 # try to use it. | 365 # try to use it. |
366 try: | 366 try: |
367 self.configDom = minidom.parse(self.userPath + 'server_ini.xml') | 367 self.configDom = minidom.parse(self.userPath + 'server_ini.xml') |
368 self.configDom.normalize() | 368 self.configDom.normalize() |
369 self.configDoc = self.configDom.documentElement | 369 self.configDoc = self.configDom.documentElement |
370 # Obtain the lobby/server password if it's been specified | 370 |
371 if self.configDoc.hasAttribute("admin"): | 371 if hasattr(self, 'bootPassword'): self.boot_pwd = self.bootPassword |
372 self.boot_pwd = self.configDoc.getAttribute("admin") | 372 |
373 elif self.configDoc.hasAttribute("boot"): | 373 else: |
374 self.boot_pwd = self.configDoc.getAttribute("boot") | 374 if self.configDoc.hasAttribute("admin"): self.boot_pwd = self.configDoc.getAttribute("admin") |
375 if hasattr(self, 'bootPassword'): | 375 elif self.configDoc.hasAttribute("boot"): self.boot_pwd = self.configDoc.getAttribute("boot") |
376 self.boot_pwd = self.bootPassword | 376 |
377 elif len(self.boot_pwd) < 1: | 377 if len(self.boot_pwd) < 1: self.boot_pwd = raw_input("Enter admin password: ") |
378 self.boot_pwd = raw_input("Enter boot password for the Lobby: ") | 378 |
379 if not hasattr(self, 'reg') and self.configDoc.hasAttribute("register"): | 379 if not hasattr(self, 'reg') and self.configDoc.hasAttribute("register"): |
380 self.reg = self.configDoc.getAttribute("register") | 380 self.reg = self.configDoc.getAttribute("register") |
381 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"): | 381 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"): |
382 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ") | 382 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ") |
383 if len(opt) and (opt[0].upper() == 'Y'): | 383 if len(opt) and (opt[0].upper() == 'Y'): self.reg = 'Y' |
384 self.reg = 'Y' | 384 else: self.reg = 'N' |
385 else: | |
386 self.reg = 'N' | |
387 LobbyName = 'Lobby' | 385 LobbyName = 'Lobby' |
388 if self.configDoc.hasAttribute("lobbyname"): | 386 if self.configDoc.hasAttribute("lobbyname"): LobbyName = self.configDoc.getAttribute("lobbyname") |
389 LobbyName = self.configDoc.getAttribute("lobbyname") | |
390 map_node = service_node = self.configDoc.getElementsByTagName("map")[0] | 387 map_node = service_node = self.configDoc.getElementsByTagName("map")[0] |
391 msg_node = service_node = self.configDoc.getElementsByTagName("message")[0] | 388 msg_node = service_node = self.configDoc.getElementsByTagName("message")[0] |
392 mapFile = map_node.getAttribute('file') | 389 mapFile = map_node.getAttribute('file') |
393 msgFile = msg_node.getAttribute('file') | 390 msgFile = msg_node.getAttribute('file') |
394 if mapFile == '': | 391 if mapFile == '': mapFile = 'Lobby_map.xml' |
395 mapFile = 'Lobby_map.xml' | 392 if msgFile == '': msgFile = 'LobbyMessage.html' |
396 if msgFile == '': | |
397 msgFile = 'LobbyMessage.html' | |
398 # Update the lobby with the passwords if they've been specified | 393 # Update the lobby with the passwords if they've been specified |
399 if len(self.boot_pwd): | 394 if len(self.boot_pwd): |
400 self.groups = {'0': game_group( '0', LobbyName, "", 'The game lobby', self.boot_pwd, "", | 395 self.groups = {'0': game_group( '0', LobbyName, "", 'The game lobby', self.boot_pwd, "", |
401 self.userPath + mapFile.replace("myfiles/", ""), | 396 self.userPath + mapFile.replace("myfiles/", ""), |
402 self.userPath + msgFile.replace("myfiles/", ""), 1 ) | 397 self.userPath + msgFile.replace("myfiles/", ""), 1 ) |
404 | 399 |
405 # set ip or dns name to send to meta server | 400 # set ip or dns name to send to meta server |
406 service_node = self.configDoc.getElementsByTagName("service")[0] | 401 service_node = self.configDoc.getElementsByTagName("service")[0] |
407 address = service_node.getAttribute("address") | 402 address = service_node.getAttribute("address") |
408 address = address.lower() | 403 address = address.lower() |
409 if address == "" or address == "hostname/address" or address == "localhost": | 404 if address == "" or address == "hostname/address" or address == "localhost": self.server_address = None |
410 self.server_address = None | 405 else: self.server_address = address |
411 else: | |
412 self.server_address = address | |
413 self.server_port = OPENRPG_PORT | 406 self.server_port = OPENRPG_PORT |
414 if service_node.hasAttribute("port"): | 407 if service_node.hasAttribute("port"): self.server_port = int(service_node.getAttribute("port")) |
415 self.server_port = int(service_node.getAttribute("port")) | |
416 if self.configDoc.hasAttribute("name") and len(self.configDoc.getAttribute("name")) > 0 : | 408 if self.configDoc.hasAttribute("name") and len(self.configDoc.getAttribute("name")) > 0 : |
417 self.name = self.configDoc.getAttribute("name") | 409 self.name = self.configDoc.getAttribute("name") |
418 else: | 410 else: |
419 if self.reg[0].upper() == "Y": | 411 if self.reg[0].upper() == "Y": |
420 if self.name == None: | 412 if self.name == None: self.name = raw_input("Server Name? ") |
421 self.name = raw_input("Server Name? ") | |
422 self.register() | 413 self.register() |
423 | 414 |
424 # Get the minimum openrpg version from config if available | 415 # Get the minimum openrpg version from config if available |
425 # if it isn't set min version to internal default. | 416 # if it isn't set min version to internal default. |
426 # | 417 # |
427 # server_ini.xml entry for version tag... | 418 # server_ini.xml entry for version tag... |
428 # <version min="x.x.x"> | 419 # <version min="x.x.x"> |
429 try: | 420 try: |
430 mver = self.configDoc.getElementsByTagName("version")[0] | 421 mver = self.configDoc.getElementsByTagName("version")[0] |
431 self.minClientVersion = mver.getAttribute("min") | 422 self.minClientVersion = mver.getAttribute("min") |
432 except: | 423 except: self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py |
433 self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py | |
434 self.defaultMessageFile = "" | 424 self.defaultMessageFile = "" |
435 # This try/except bit is to allow older versions of python to continue without a list error. | 425 # This try/except bit is to allow older versions of python to continue without a list error. |
436 | 426 |
437 | 427 |
438 | 428 |
444 # <autokick silent=["no","yes"] delay="(# of seconds)"> | 434 # <autokick silent=["no","yes"] delay="(# of seconds)"> |
445 | 435 |
446 try: | 436 try: |
447 ak = self.configDoc.getElementsByTagName("autokick")[0] | 437 ak = self.configDoc.getElementsByTagName("autokick")[0] |
448 if ak.hasAttribute("silent"): | 438 if ak.hasAttribute("silent"): |
449 if ((ak.getAttribute("silent")).lower() == "yes"): | 439 if ((ak.getAttribute("silent")).lower() == "yes"): self.silent_auto_kick = 1 |
450 self.silent_auto_kick = 1 | 440 else: self.silent_auto_kick = 0 |
451 else: | |
452 self.silent_auto_kick = 0 | |
453 if ak.hasAttribute("delay"): | 441 if ak.hasAttribute("delay"): |
454 try: | 442 try: |
455 delay = int(ak.getAttribute("delay")) | 443 delay = int(ak.getAttribute("delay")) |
456 self.zombie_time = delay | 444 self.zombie_time = delay |
457 except: | 445 except: |
495 setting = roomdefaults.getElementsByTagName('passwords')[0] | 483 setting = roomdefaults.getElementsByTagName('passwords')[0] |
496 rpw = setting.getAttribute('allow') | 484 rpw = setting.getAttribute('allow') |
497 if rpw == "no" or rpw == "0": | 485 if rpw == "no" or rpw == "0": |
498 roomdefault_pass = 0 | 486 roomdefault_pass = 0 |
499 self.log_msg("Room Defaults: Disallowing Passworded Rooms") | 487 self.log_msg("Room Defaults: Disallowing Passworded Rooms") |
500 else: | 488 else: self.log_msg("Room Defaults: Allowing Passworded Rooms") |
501 self.log_msg("Room Defaults: Allowing Passworded Rooms") | 489 except: self.log_msg("Room Defaults: [Warning] Allowing Passworded Rooms") |
502 except: | |
503 self.log_msg("Room Defaults: [Warning] Allowing Passworded Rooms") | |
504 try: | 490 try: |
505 setting = roomdefaults.getElementsByTagName('map')[0] | 491 setting = roomdefaults.getElementsByTagName('map')[0] |
506 map = setting.getAttribute('file') | 492 map = setting.getAttribute('file') |
507 if map != "": | 493 if map != "": |
508 roomdefault_map = self.userPath + map.replace("myfiles/", "") | 494 roomdefault_map = self.userPath + map.replace("myfiles/", "") |
512 | 498 |
513 try: | 499 try: |
514 setting = roomdefaults.getElementsByTagName('message')[0] | 500 setting = roomdefaults.getElementsByTagName('message')[0] |
515 msg = setting.getAttribute('file') | 501 msg = setting.getAttribute('file') |
516 if msg != "": | 502 if msg != "": |
517 if msg[:4].lower() == 'http': | 503 if msg[:4].lower() == 'http': roomdefault_msg = msg |
518 roomdefault_msg = msg | 504 else: roomdefault_msg = self.userPath + msg.replace("myfiles/", "") |
519 else: | |
520 roomdefault_msg = self.userPath + msg.replace("myfiles/", "") | |
521 self.log_msg("Room Defaults: Using " + str(msg) + " for room messages") | 505 self.log_msg("Room Defaults: Using " + str(msg) + " for room messages") |
522 except: | 506 except: print ("Room Defaults: [Warning] Using Default Message") |
523 print ("Room Defaults: [Warning] Using Default Message") | |
524 except: | 507 except: |
525 traceback.print_exc() | 508 traceback.print_exc() |
526 self.log_msg("**WARNING** Error loading default room settings from configuration file. Using internal defaults.") | 509 self.log_msg("**WARNING** Error loading default room settings from configuration file. Using internal defaults.") |
527 | 510 |
528 | 511 |
529 #set the defaults | 512 #set the defaults |
530 if roomdefault_msg != "" or roomdefault_msg != None: | 513 if roomdefault_msg != "" or roomdefault_msg != None: |
531 self.defaultMessageFile = roomdefault_msg #<room_defaults> tag superceeds older <newrooms> tag | 514 self.defaultMessageFile = roomdefault_msg #<room_defaults> tag superceeds older <newrooms> tag |
532 else: | 515 else: self.defaultMessageFile = None |
533 self.defaultMessageFile = None | |
534 | 516 |
535 if roomdefault_map != "" or roomdefault_map != None: | 517 if roomdefault_map != "" or roomdefault_map != None: |
536 self.defaultMapFile = roomdefault_map #<room_defaults> tag superceeds older <newrooms> tag | 518 self.defaultMapFile = roomdefault_map #<room_defaults> tag superceeds older <newrooms> tag |
537 else: | 519 else: self.defaultMapFile = None |
538 self.defaultMapFile = None | |
539 | 520 |
540 ##### room default map not handled yet. SETTING IGNORED | 521 ##### room default map not handled yet. SETTING IGNORED |
541 if roomdefault_pass == 0: self.allow_room_passwords = 0 | 522 if roomdefault_pass == 0: self.allow_room_passwords = 0 |
542 else: self.allow_room_passwords = 1 | 523 else: self.allow_room_passwords = 1 |
543 | 524 |
557 # should validate protocal | 538 # should validate protocal |
558 validate_protocol_node = self.configDom.getElementsByTagName("validate_protocol ") | 539 validate_protocol_node = self.configDom.getElementsByTagName("validate_protocol ") |
559 | 540 |
560 self.validate_protocol = 1 | 541 self.validate_protocol = 1 |
561 | 542 |
562 if(validate_protocol_node): | 543 if(validate_protocol_node): self.validate_protocol = (validate_protocol_node[0].getAttribute("value") == "True") |
563 self.validate_protocol = (validate_protocol_node[0].getAttribute("value") == "True") | 544 if(self.validate_protocol != 1): self.log_msg("Protocol Validation: OFF") |
564 if(self.validate_protocol != 1): | |
565 self.log_msg("Protocol Validation: OFF") | |
566 self.makePersistentRooms() | 545 self.makePersistentRooms() |
567 | 546 |
568 self.log_msg("Server Configuration File: Processing Completed.") | 547 self.log_msg("Server Configuration File: Processing Completed.") |
569 | 548 |
570 except Exception, e: | 549 except Exception, e: |
579 roomName = element.getAttribute('name') | 558 roomName = element.getAttribute('name') |
580 roomPassword = element.getAttribute('password') | 559 roomPassword = element.getAttribute('password') |
581 bootPassword = element.getAttribute('boot') | 560 bootPassword = element.getAttribute('boot') |
582 | 561 |
583 # Conditionally check for minVersion attribute | 562 # Conditionally check for minVersion attribute |
584 if element.hasAttribute('minVersion'): | 563 if element.hasAttribute('minVersion'): minVersion = element.getAttribute('minVersion') |
585 minVersion = element.getAttribute('minVersion') | 564 else: minVersion = "" |
586 else: | |
587 minVersion = "" | |
588 | 565 |
589 # Extract the map filename attribute from the map node | 566 # Extract the map filename attribute from the map node |
590 # we only care about the first map element found -- others are ignored | 567 # we only care about the first map element found -- others are ignored |
591 mapElement = element.getElementsByTagName('map')[0] | 568 mapElement = element.getElementsByTagName('map')[0] |
592 mapFile = self.userPath + mapElement.getAttribute('file').replace("myfiles/", "") | 569 mapFile = self.userPath + mapElement.getAttribute('file').replace("myfiles/", "") |
593 | 570 |
594 messageElement = element.getElementsByTagName('message')[0] | 571 messageElement = element.getElementsByTagName('message')[0] |
595 messageFile = messageElement.getAttribute('file') | 572 messageFile = messageElement.getAttribute('file') |
596 | 573 |
597 if messageFile[:4] != 'http': | 574 if messageFile[:4] != 'http': messageFile = self.userPath + messageFile.replace("myfiles/", "") |
598 messageFile = self.userPath + messageFile.replace("myfiles/", "") | |
599 | 575 |
600 # Make sure we have a message to even mess with | 576 # Make sure we have a message to even mess with |
601 if(len(messageFile) == 0): | 577 if(len(messageFile) == 0): messageFile = self.defaultMessageFile |
602 messageFile = self.defaultMessageFile | 578 |
603 | 579 if(len(mapFile) == 0): mapFile = self.defaultMapFile |
604 if(len(mapFile) == 0): | |
605 mapFile = self.defaultMapFile | |
606 | 580 |
607 moderated = 0 | 581 moderated = 0 |
608 if element.hasAttribute('moderated') and element.getAttribute('moderated').lower() == "true": | 582 if element.hasAttribute('moderated') and element.getAttribute('moderated').lower() == "true": moderated = 1 |
609 moderated = 1 | |
610 | 583 |
611 #create the new persistant group | 584 #create the new persistant group |
612 self.new_group(roomName, roomPassword, bootPassword, minVersion, mapFile, messageFile, persist = 1, moderated=moderated) | 585 self.new_group(roomName, roomPassword, bootPassword, minVersion, mapFile, messageFile, persist = 1, moderated=moderated) |
613 | 586 |
614 | 587 |
656 self.log_msg("Network Logging: ON (split logfiles)") | 629 self.log_msg("Network Logging: ON (split logfiles)") |
657 self.log_network_messages = 2 | 630 self.log_network_messages = 2 |
658 else: return | 631 else: return |
659 #when log mode changes update all connection stubs | 632 #when log mode changes update all connection stubs |
660 for n in self.players: | 633 for n in self.players: |
661 try: | 634 try: self.players[n].EnableMessageLogging = mode |
662 self.players[n].EnableMessageLogging = mode | 635 except: self.log_msg("Error changing Message Logging Mode for client #" + str(self.players[n].id)) |
663 except: | |
664 self.log_msg("Error changing Message Logging Mode for client #" + str(self.players[n].id)) | |
665 def NetworkLoggingStatus(self): | 636 def NetworkLoggingStatus(self): |
666 if self.log_network_messages == 0: return "Network Traffic Log: Off" | 637 if self.log_network_messages == 0: return "Network Traffic Log: Off" |
667 elif self.log_network_messages == 1: return "Network Traffic Log: Logging (composite file)" | 638 elif self.log_network_messages == 1: return "Network Traffic Log: Logging (composite file)" |
668 elif self.log_network_messages == 2: return "Network Traffic Log: Logging (inbound/outbound files)" | 639 elif self.log_network_messages == 2: return "Network Traffic Log: Logging (inbound/outbound files)" |
669 else: self.log_msg("Network Traffic Log: [Unknown]") | 640 else: self.log_msg("Network Traffic Log: [Unknown]") |
681 newlist = getRawMetaList() # read it into a second list | 652 newlist = getRawMetaList() # read it into a second list |
682 finally: | 653 finally: |
683 metacache_lock.release() | 654 metacache_lock.release() |
684 | 655 |
685 if newlist != curlist: # If the two lists aren't identical | 656 if newlist != curlist: # If the two lists aren't identical |
686 # then something has changed. | 657 # then something has changed. |
687 instance.register() # Call self.register() | 658 instance.register() # Call self.register() |
688 # which will force a re-read of the meta cache and | 659 # which will force a re-read of the meta cache and |
689 # redo the registerThreads | 660 # redo the registerThreads |
690 else: | 661 else: instance.register() |
691 instance.register() | |
692 | 662 |
693 # Eventually, reset the MetaServerBaseURL here | 663 # Eventually, reset the MetaServerBaseURL here |
694 | 664 |
695 ## Added to help clean up parser errors in the XML on clients | 665 ## Added to help clean up parser errors in the XML on clients |
696 ## due to characters that break welformedness of the XML from | 666 ## due to characters that break welformedness of the XML from |
697 ## the meta server. | 667 ## the meta server. |
698 ## NOTE: this is a stopgap measure -SD | 668 ## NOTE: this is a stopgap measure -SD |
699 def clean_published_servername(self, name): | 669 def clean_published_servername(self, name): |
700 #clean name of all apostrophes and quotes | 670 #clean name of all apostrophes and quotes |
701 badchars = "\"\\`><" | 671 badchars = "\"\\`><" |
702 for c in badchars: | 672 for c in badchars: name = name.replace(c,"") |
703 name = name.replace(c,"") | |
704 return name | 673 return name |
705 | 674 |
706 def registerRooms(self, args=None): | 675 def registerRooms(self, args=None): |
707 rooms = '' | 676 rooms = '' |
708 id = '0' | 677 id = '0' |
722 "act":'registerrooms'}) | 691 "act":'registerrooms'}) |
723 get_server_dom(data+'&'+rooms, self.metas[meta].path) | 692 get_server_dom(data+'&'+rooms, self.metas[meta].path) |
724 | 693 |
725 | 694 |
726 def register(self,name_given=None): | 695 def register(self,name_given=None): |
727 if name_given == None: | 696 if name_given == None: name = self.name |
728 name = self.name | 697 else: self.name = name = name_given |
729 else: | |
730 self.name = name = name_given | |
731 | 698 |
732 name = self.clean_published_servername(name) | 699 name = self.clean_published_servername(name) |
733 | 700 |
734 # Set up the value for num_users | 701 # Set up the value for num_users |
735 if self.players: | 702 if self.players: num_players = len(self.players) |
736 num_players = len(self.players) | 703 else: num_players = 0 |
737 else: | |
738 num_players = 0 | |
739 | 704 |
740 # request only Meta servers compatible with version 2 | 705 # request only Meta servers compatible with version 2 |
741 metalist = getMetaServers(versions=["2"]) | 706 metalist = getMetaServers(versions=["2"]) |
742 if self.show_meta_messages != 0: | 707 if self.show_meta_messages != 0: |
743 self.log_msg("Found these valid metas:") | 708 self.log_msg("Found these valid metas:") |
744 for meta in metalist: | 709 for meta in metalist: self.log_msg("Meta:" + meta) |
745 self.log_msg("Meta:" + meta) | |
746 | 710 |
747 # Go through the list and see if there is already a running register | 711 # Go through the list and see if there is already a running register |
748 # thread for the meta. | 712 # thread for the meta. |
749 # If so, call it's register() method | 713 # If so, call it's register() method |
750 # If not, start one, implicitly calling the new thread's register() method | 714 # If not, start one, implicitly calling the new thread's register() method |
757 if self.show_meta_messages != 0: self.log_msg("meta:" + meta + ": ") | 721 if self.show_meta_messages != 0: self.log_msg("meta:" + meta + ": ") |
758 if not meta in metalist: # if the meta entry running is not in the list | 722 if not meta in metalist: # if the meta entry running is not in the list |
759 if self.show_meta_messages != 0: self.log_msg( "Outdated. Unregistering and removing") | 723 if self.show_meta_messages != 0: self.log_msg( "Outdated. Unregistering and removing") |
760 self.metas[meta].unregister() | 724 self.metas[meta].unregister() |
761 del self.metas[meta] | 725 del self.metas[meta] |
762 else: | 726 else: |
763 if self.show_meta_messages != 0: self.log_msg( "Found in current meta list. Leaving intact.") | 727 if self.show_meta_messages != 0: self.log_msg( "Found in current meta list. Leaving intact.") |
764 | 728 |
765 # Now call register() for alive metas or start one if we need one | 729 # Now call register() for alive metas or start one if we need one |
766 for meta in metalist: | 730 for meta in metalist: |
767 if self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive(): | 731 if self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive(): |
784 # would never get unregistered. | 748 # would never get unregistered. |
785 # | 749 # |
786 # Instead, loop through all existing meta threads and unregister them | 750 # Instead, loop through all existing meta threads and unregister them |
787 | 751 |
788 for meta in self.metas.values(): | 752 for meta in self.metas.values(): |
789 if meta and meta.isAlive(): | 753 if meta and meta.isAlive(): meta.unregister() |
790 meta.unregister() | |
791 | |
792 self.be_registered = 0 | 754 self.be_registered = 0 |
793 | 755 |
794 | 756 # This method runs as it's own thread and does the group_member_check every |
795 | 757 # sixty seconds. This should eliminate zombies that linger when no one is |
796 | 758 # around to spook them. GC: Frequency has been reduced as I question how valid |
797 # This method runs as it's own thread and does the group_member_check every | 759 # the implementation is as it will only catch a very small segment of lingering |
798 # sixty seconds. This should eliminate zombies that linger when no one is | 760 # connections. |
799 # around to spook them. GC: Frequency has been reduced as I question how valid | |
800 # the implementation is as it will only catch a very small segment of lingering | |
801 # connections. | |
802 def player_reaper_thread_func(self,arg): | 761 def player_reaper_thread_func(self,arg): |
803 while self.alive: | 762 while self.alive: |
804 time.sleep(60) | 763 time.sleep(60) |
805 | 764 |
806 self.p_lock.acquire() | 765 self.p_lock.acquire() |
807 for group in self.groups.keys(): | 766 for group in self.groups.keys(): self.check_group_members(group) |
808 self.check_group_members(group) | |
809 self.p_lock.release() | 767 self.p_lock.release() |
810 | 768 |
811 #This thread runs ever 250 miliseconds, and checks various plugin stuff | 769 #This thread runs ever 250 miliseconds, and checks various plugin stuff |
812 def PluginThread(self): | 770 def PluginThread(self): |
813 while self.alive: | 771 while self.alive: |
814 self.p_lock.acquire() | 772 self.p_lock.acquire() |
815 players = ServerPlugins.getPlayer() | 773 players = ServerPlugins.getPlayer() |
816 | 774 |
817 for player in players: | 775 for player in players: |
818 if player is not None: | 776 if player is not None: pass #Do something here so they can show up in the chat room for non web users' |
819 #Do something here so they can show up in the chat room for non web users' | |
820 pass | |
821 | |
822 data = ServerPlugins.preParseOutgoing() | 777 data = ServerPlugins.preParseOutgoing() |
823 | |
824 for msg in data: | 778 for msg in data: |
825 try: | 779 try: |
826 xml_dom = parseXml(msg) | 780 xml_dom = parseXml(msg) |
827 xml_dom = xml_dom._get_documentElement() | 781 xml_dom = xml_dom._get_documentElement() |
828 | 782 |
830 xml_dom.setAttribute('from', '-1') | 784 xml_dom.setAttribute('from', '-1') |
831 | 785 |
832 xml_dom.setAttribute('to', 'all') | 786 xml_dom.setAttribute('to', 'all') |
833 self.incoming_msg_handler(xml_dom, msg) | 787 self.incoming_msg_handler(xml_dom, msg) |
834 xml_dom.unlink() | 788 xml_dom.unlink() |
835 except: | 789 except: pass |
836 pass | |
837 | 790 |
838 self.p_lock.release() | 791 self.p_lock.release() |
839 time.sleep(0.250) | 792 time.sleep(0.250) |
840 | 793 |
841 | 794 |
852 while offset < len(mpacket): | 805 while offset < len(mpacket): |
853 slice = buffer(mpacket, offset, len(mpacket)-offset) | 806 slice = buffer(mpacket, offset, len(mpacket)-offset) |
854 sent = sock.send(slice) | 807 sent = sock.send(slice) |
855 offset += sent | 808 offset += sent |
856 sentm = offset | 809 sentm = offset |
857 else: | 810 else: |
858 # Calculate our message length | 811 length = len( msg ) # Calculate our message length |
859 length = len( msg ) | 812 lp = pack('!i', length) # Encode the message length into network byte order |
860 | |
861 # Encode the message length into network byte order | |
862 lp = pack('!i', length) | |
863 | |
864 try: | 813 try: |
865 # Send the encoded length | 814 sentl = sock.send( lp ) # Send the encoded length |
866 sentl = sock.send( lp ) | 815 sentm = sock.send( msg ) # Now, send the message the the length was describing |
867 | 816 except socket.error, e: self.log_msg( e ) |
868 # Now, send the message the the length was describing | 817 except Exception, e: self.log_msg( e ) |
869 sentm = sock.send( msg ) | |
870 | |
871 except socket.error, e: | |
872 self.log_msg( e ) | |
873 | |
874 except Exception, e: | |
875 self.log_msg( e ) | |
876 | 818 |
877 | 819 |
878 def recvData( self, sock, readSize ): | 820 def recvData( self, sock, readSize ): |
879 """Simple socket receive method. This method will only return when the exact | 821 """Simple socket receive method. This method will only return when the exact |
880 byte count has been read from the connection, if remote terminates our | 822 byte count has been read from the connection, if remote terminates our |
883 data = "" | 825 data = "" |
884 offset = 0 | 826 offset = 0 |
885 try: | 827 try: |
886 while offset != readSize: | 828 while offset != readSize: |
887 frag = sock.recv( readSize - offset ) | 829 frag = sock.recv( readSize - offset ) |
888 | 830 rs = len( frag ) # See if we've been disconnected |
889 # See if we've been disconnected | |
890 rs = len( frag ) | |
891 if rs <= 0: | 831 if rs <= 0: |
892 # Loudly raise an exception because we've been disconnected! | 832 # Loudly raise an exception because we've been disconnected! |
893 raise IOError, "Remote closed the connection!" | 833 raise IOError, "Remote closed the connection!" |
894 | 834 else: # Continue to build complete message |
895 else: | |
896 # Continue to build complete message | |
897 offset += rs | 835 offset += rs |
898 data += frag | 836 data += frag |
899 | 837 |
900 except socket.error, e: | 838 except socket.error, e: |
901 self.log_msg("Socket Error: recvData(): " + e ) | 839 self.log_msg("Socket Error: recvData(): " + e ) |
902 data = "" | 840 data = "" |
903 | |
904 return data | 841 return data |
905 | |
906 | |
907 | 842 |
908 def recvMsg(self, sock, useCompression=False, cmpType=None): | 843 def recvMsg(self, sock, useCompression=False, cmpType=None): |
909 """This method now expects to receive a message having a 4-byte prefix length. It will ONLY read | 844 """This method now expects to receive a message having a 4-byte prefix length. It will ONLY read |
910 completed messages. In the event that the remote's connection is terminated, it will throw an | 845 completed messages. In the event that the remote's connection is terminated, it will throw an |
911 exception which should allow for the caller to more gracefully handles this exception event. | 846 exception which should allow for the caller to more gracefully handles this exception event. |
916 with the OS until we attempt to read the next complete message.""" | 851 with the OS until we attempt to read the next complete message.""" |
917 | 852 |
918 msgData = "" | 853 msgData = "" |
919 try: | 854 try: |
920 lenData = self.recvData( sock, MPLAY_LENSIZE ) | 855 lenData = self.recvData( sock, MPLAY_LENSIZE ) |
921 | |
922 # Now, convert to a usable form | 856 # Now, convert to a usable form |
923 (length,) = unpack('!i', lenData) | 857 (length,) = unpack('!i', lenData) |
924 | |
925 # Read exactly the remaining amount of data | 858 # Read exactly the remaining amount of data |
926 msgData = self.recvData( sock, length ) | 859 msgData = self.recvData( sock, length ) |
927 | |
928 try: | 860 try: |
929 if useCompression and cmpType != None: | 861 if useCompression and cmpType != None: msgData = cmpType.decompress(msgData) |
930 msgData = cmpType.decompress(msgData) | 862 except: traceback.print_exc() |
931 except: | 863 |
932 traceback.print_exc() | 864 except Exception, e: self.log_msg( "Exception: recvMsg(): " + str(e) ) |
933 | |
934 except Exception, e: | |
935 self.log_msg( "Exception: recvMsg(): " + str(e) ) | |
936 | |
937 return msgData | 865 return msgData |
938 | |
939 | 866 |
940 | 867 |
941 def kill_server(self): | 868 def kill_server(self): |
942 self.alive = 0 | 869 self.alive = 0 |
943 self.log_msg("Server stopping...") | 870 self.log_msg("Server stopping...") |
1355 | 1282 |
1356 # Re-initialize the role for this player incase they came from a different server | 1283 # Re-initialize the role for this player incase they came from a different server |
1357 self.handle_role("set",props['id'], "GM",self.groups[LOBBY_ID].boot_pwd, LOBBY_ID) | 1284 self.handle_role("set",props['id'], "GM",self.groups[LOBBY_ID].boot_pwd, LOBBY_ID) |
1358 | 1285 |
1359 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" | 1286 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" |
1287 self.log_msg(cmsg) | |
1288 cmsg = ("connect", props) ################################################# | |
1360 self.log_msg(cmsg) | 1289 self.log_msg(cmsg) |
1361 | 1290 |
1362 # If already registered then re-register, thereby updating the Meta | 1291 # If already registered then re-register, thereby updating the Meta |
1363 # on the number of players | 1292 # on the number of players |
1364 if self.be_registered: | 1293 if self.be_registered: |
1862 # this line sends a handle role message to change the players role | 1791 # this line sends a handle role message to change the players role |
1863 self.send_player_list(from_id,group_id) | 1792 self.send_player_list(from_id,group_id) |
1864 | 1793 |
1865 #notify user about others in the room | 1794 #notify user about others in the room |
1866 self.return_room_roles(from_id,group_id) | 1795 self.return_room_roles(from_id,group_id) |
1867 self.log_msg(("join_group", (from_id, group_id))) | 1796 self.log_msg(("join_group", (self.groups[group_id].name, group_id, from_id))) |
1868 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) | 1797 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) |
1869 | 1798 |
1870 except Exception, e: | 1799 except Exception, e: |
1871 self.log_msg(str(e)) | 1800 self.log_msg(str(e)) |
1872 | 1801 |
1885 # send them to players. Also note, both these methods have race | 1814 # send them to players. Also note, both these methods have race |
1886 # conditions written all over them. Ack! Ack! | 1815 # conditions written all over them. Ack! Ack! |
1887 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ): | 1816 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ): |
1888 group_id = str( self.next_group_id ) | 1817 group_id = str( self.next_group_id ) |
1889 self.next_group_id += 1 | 1818 self.next_group_id += 1 |
1890 | |
1891 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist ) | 1819 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist ) |
1892 self.groups[group_id].moderated = moderated | 1820 self.groups[group_id].moderated = moderated |
1893 ins = "" | 1821 ins = "" |
1894 if persist !=0: ins="Persistant " | 1822 if persist !=0: ins="Persistant " |
1895 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) | 1823 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) |
1896 self.log_msg( lmsg ) | 1824 self.log_msg( lmsg ) |
1825 self.log_msg(("create_group", (str(name), int(group_id), 0) )) ##-99 works, could be better. | |
1897 | 1826 |
1898 | 1827 |
1899 def change_group_name(self,gid,name,pid): | 1828 def change_group_name(self,gid,name,pid): |
1900 "Change the name of a group" | 1829 "Change the name of a group" |
1901 # Check for & in name. We want to allow this because of its common | 1830 # Check for & in name. We want to allow this because of its common |
2006 self.handle_role("set",from_id,"GM",boot_pwd, group_id) | 1935 self.handle_role("set",from_id,"GM",boot_pwd, group_id) |
2007 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name) | 1936 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name) |
2008 self.log_msg( lmsg ) | 1937 self.log_msg( lmsg ) |
2009 jmsg = "moving to room " + str(group_id) + "." | 1938 jmsg = "moving to room " + str(group_id) + "." |
2010 self.log_msg( jmsg ) | 1939 self.log_msg( jmsg ) |
1940 self.log_msg(("create_group", (str(name), group_id, from_id))) | |
2011 #even creators of the room should see the HTML --akoman | 1941 #even creators of the room should see the HTML --akoman |
2012 #edit: jan10/03 - was placed in the except statement. Silly me. | 1942 #edit: jan10/03 - was placed in the except statement. Silly me. |
2013 if self.defaultMessageFile != None: | 1943 if self.defaultMessageFile != None: |
2014 if self.defaultMessageFile[:4] == 'http': | 1944 if self.defaultMessageFile[:4] == 'http': |
2015 data = urllib.urlretrieve(self.defaultMessageFile) | 1945 data = urllib.urlretrieve(self.defaultMessageFile) |
2036 self.send_to_all("0",self.groups[group_id].toxml('update')) | 1966 self.send_to_all("0",self.groups[group_id].toxml('update')) |
2037 return #never remove lobby *sanity check* | 1967 return #never remove lobby *sanity check* |
2038 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0: | 1968 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0: |
2039 self.send_to_all("0",self.groups[group_id].toxml('del')) | 1969 self.send_to_all("0",self.groups[group_id].toxml('del')) |
2040 del self.groups[group_id] | 1970 del self.groups[group_id] |
2041 self.log_msg(("delete_group", (from_id, group_id))) | 1971 self.log_msg(("delete_group", (group_id, from_id))) |
2042 | 1972 |
2043 else: | 1973 else: |
2044 self.send_to_all("0",self.groups[group_id].toxml('update')) | 1974 self.send_to_all("0",self.groups[group_id].toxml('update')) |
2045 | 1975 |
2046 #The register Rooms thread | 1976 #The register Rooms thread |
2054 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) | 1984 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) |
2055 self.players[id].disconnect() | 1985 self.players[id].disconnect() |
2056 self.groups[group_id].remove_player(id) | 1986 self.groups[group_id].remove_player(id) |
2057 del self.players[id] | 1987 del self.players[id] |
2058 self.log_msg(dmsg) | 1988 self.log_msg(dmsg) |
1989 self.log_msg(("disconnect",id)) | |
2059 | 1990 |
2060 | 1991 |
2061 # If already registered then re-register, thereby updating the Meta | 1992 # If already registered then re-register, thereby updating the Meta |
2062 # on the number of players | 1993 # on the number of players |
2063 # Note: Upon server shutdown, the server is first unregistered, so | 1994 # Note: Upon server shutdown, the server is first unregistered, so |
2463 self.players[player].send(msg,player,group) | 2394 self.players[player].send(msg,player,group) |
2464 | 2395 |
2465 | 2396 |
2466 def send_to_all(self,from_id,data): | 2397 def send_to_all(self,from_id,data): |
2467 try: | 2398 try: |
2399 print data | |
2468 self.p_lock.acquire() | 2400 self.p_lock.acquire() |
2469 keys = self.players.keys() | 2401 keys = self.players.keys() |
2470 self.p_lock.release() | 2402 self.p_lock.release() |
2471 for k in keys: | 2403 for k in keys: |
2472 if k != from_id: | 2404 if k != from_id: |
2473 self.players[k].outbox.put(data) | 2405 self.players[k].outbox.put(data) |
2474 except Exception, e: | 2406 except Exception, e: |
2475 traceback.print_exc() | 2407 traceback.print_exc() |
2476 self.log_msg("Exception: send_to_all(): " + str(e)) | 2408 self.log_msg("Exception: send_to_all(): " + str(e)) |
2477 | 2409 |
2478 | |
2479 | |
2480 def send_to_group(self, from_id, group_id, data): | 2410 def send_to_group(self, from_id, group_id, data): |
2481 data = ServerPlugins.postParseIncoming(data) | 2411 msg = ("<msg to='all' from='0' group_id='"+group_id+"'><font color='#FF0000'>" + data + "</font>") |
2482 try: | 2412 #data = ServerPlugins.postParseIncoming(data) |
2413 try: | |
2414 print data | |
2415 self.p_lock.acquire() | |
2483 keys = self.groups[group_id].get_player_ids() | 2416 keys = self.groups[group_id].get_player_ids() |
2417 self.p_lock.release() | |
2418 print keys | |
2484 for k in keys: | 2419 for k in keys: |
2485 if k != from_id: | 2420 if k != from_id: |
2486 self.players[k].outbox.put(data) | 2421 self.players[k].outbox.put(msg) |
2487 except Exception, e: | 2422 except Exception, e: |
2488 traceback.print_exc() | 2423 traceback.print_exc() |
2489 self.log_msg("Exception: send_to_group(): " + str(e)) | 2424 self.log_msg("Exception: send_to_group(): " + str(e)) |
2490 | 2425 |
2491 def send_player_list(self,to_id,group_id): | 2426 def send_player_list(self,to_id,group_id): |