123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- """DWC Network Server Emulator
- Copyright (C) 2014 polaris-
- Copyright (C) 2014 ToadKing
- Copyright (C) 2014 AdmiralCurtiss
- Copyright (C) 2016 Sepalani
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- """
- def parse_gamespy_message(message):
- """Parse a GameSpy message."""
- stack = []
- messages = {}
- msg = message
- while len(msg) > 0 and msg[0] == '\\' and "\\final\\" in msg:
- # Find the command
- # Don't search for more commands if there isn't a \final\, save the
- # left over for the next packet
- found_command = False
- while len(msg) > 0 and msg[0] == '\\':
- keyEnd = msg[1:].index('\\') + 1
- key = msg[1:keyEnd]
- msg = msg[keyEnd + 1:]
- if key == "final":
- break
- if '\\' in msg:
- if msg[0] == '\\':
- value = ""
- else:
- valueEnd = msg[1:].index('\\')
- value = msg[:valueEnd + 1]
- msg = msg[valueEnd + 1:]
- else:
- value = msg
- if not found_command:
- messages['__cmd__'] = key
- messages['__cmd_val__'] = value
- found_command = True
- messages[key] = value
- stack.append(messages)
- messages = {}
- # Return msg so we can prepend any leftover commands to the next packet.
- return stack, msg
- def create_gamespy_message_from_dict(messages):
- """Generate a list based on the input dictionary.
- The main command must also be stored in __cmd__ for it to put the
- parameter at the beginning.
- """
- cmd = messages.get("__cmd__", "")
- cmd_val = messages.get("__cmd_val__", "")
- l = [("__cmd__", cmd), ("__cmd_val__", cmd_val)]
- l.extend([
- (key, value)
- for key, value in messages.items()
- if key not in (cmd, "__cmd__", "__cmd_val__")
- ])
- return l
- def create_gamespy_message_from_list(messages):
- """Generate a string based on the input list."""
- cmd = ""
- cmd_val = ""
- query = ""
- for message in messages:
- if len(message) == 1:
- query += str(message[0])
- elif message[0] == "__cmd__":
- cmd = str(message[1]).strip('\\')
- elif message[0] == "__cmd_val__":
- cmd_val = str(message[1]).strip('\\')
- else:
- query += "\\%s\\%s" % (str(message[0]).strip('\\'),
- str(message[1]).strip('\\'))
- if cmd:
- # Prepend the main command if one was found.
- query = "\\%s\\%s%s" % (cmd, cmd_val, query)
- return query
- def create_gamespy_message(messages, id=None):
- """Create a message based on a dictionary (or list) of parameters."""
- if isinstance(messages, dict):
- messages = create_gamespy_message_from_dict(messages)
- # Check for an id if the id needs to be updated.
- if id is not None:
- for i, message in enumerate(messages):
- # If it already exists in the list then update it
- if message[0] == "id":
- messages[i] = ("id", str(id))
- break
- else:
- # Otherwise, add it in the list
- messages.append(("id", str(id)))
- query = create_gamespy_message_from_list(messages)
- query += "\\final\\"
- return query
|