Skip to content

Commit b63dc3e

Browse files
author
yorickvanpelt
committed
- Codechange: make openttdlib a module
1 parent edbdbf7 commit b63dc3e

14 files changed

+302
-296
lines changed

newgrfs.grflist

702 Bytes
Binary file not shown.

openttd/__init__.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# OpenTTD python module
2+
# http://openttd-python.googlecode.com/
3+
4+
# Ensure the user is running the version of python we require.
5+
import sys
6+
if not hasattr(sys, "version_info") or sys.version_info < (2,4):
7+
raise RuntimeError("OpenTTD-Python requires Python 2.4 or later.")
8+
del sys
9+
10+
import client
11+
import savegame
12+
from datastorageclass import DataStorageClass
13+
import date
14+
import grfdb

ottd_lib.py renamed to openttd/client.py

+29-56
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/bin/env python
22
# made by thomas in 5 hours - no guarantees ;)
33
import sys, struct
4-
import logging, logging.config
54
import threading
65
import socket
76
import random
@@ -12,39 +11,19 @@
1211
import copy
1312
import traceback
1413
import StringIO
15-
import datetime
1614
from operator import itemgetter
1715
from struct_zerostrings import *
18-
from ottd_constants import *
1916
import signal
2017
from log import LOG
21-
22-
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "lib"))
18+
import constants as const
19+
from datastorageclass import DataStorageClass
2320

2421
#connection modes
2522
M_NONE = 0
26-
M_TCP = 1
27-
M_UDP = 2
23+
M_TCP = 1 << 0
24+
M_UDP = 1 << 1
2825
M_BOTH = M_TCP | M_UDP
2926

30-
class DataStorageClass(object):
31-
def __init__(self, dict={}):
32-
self.__dict__ = dict
33-
def __getitem__(self, key):
34-
return self.__dict__[key]
35-
def __getattr__(self, key):
36-
if key in self.__dict__:
37-
return self.__dict__[key]
38-
else:
39-
raise AttributeError
40-
def __setattr__(self, key, value):
41-
if not key == "__dict__":
42-
self.__dict__[key] = value
43-
def __delattr__(self, key):
44-
del self.__dict__[key]
45-
def getDict(self):
46-
return self.__dict__
47-
4827
class DataPacket:
4928
size=0
5029
command=0
@@ -112,7 +91,6 @@ def __init__(self, ip, port, debugLevel=0, uid=None):
11291
self.debuglevel = debugLevel
11392
self.uid = uid
11493

115-
LOG.debug('__init__')
11694
self.running = True # sighandler will change this value
11795
self.lock = threading.Lock()
11896
threading.Thread.__init__(self)
@@ -149,7 +127,7 @@ def connect(self, mode=M_BOTH):
149127

150128
#self.throwRandomData()
151129
#self.packetTest()
152-
#self.sendMsg_UDP(PACKET_UDP_CLIENT_FIND_SERVER)
130+
#self.sendMsg_UDP(const.PACKET_UDP_CLIENT_FIND_SERVER)
153131
#self.sendRaw(self.packetTest())
154132
#data=self.receiveMsg_UDP()
155133

@@ -180,10 +158,10 @@ def run(self):
180158
pass
181159

182160
def getServerList(self):
183-
payload = struct.pack("B", NETWORK_MASTER_SERVER_VERSION)
184-
self.sendMsg_UDP(PACKET_UDP_CLIENT_GET_LIST, payload)
161+
payload = struct.pack("B", const.NETWORK_MASTER_SERVER_VERSION)
162+
self.sendMsg_UDP(const.PACKET_UDP_CLIENT_GET_LIST, payload)
185163
p = self.receiveMsg_UDP(datapacket=True)
186-
if p.command == PACKET_UDP_MASTER_RESPONSE_LIST:
164+
if p.command == const.PACKET_UDP_MASTER_RESPONSE_LIST:
187165
protocol_version = p.recv_uint8()
188166

189167
if protocol_version == 1:
@@ -202,7 +180,7 @@ def getServerList(self):
202180

203181

204182
def getGRFInfo(self, grfs):
205-
p = DataPacket(0, PACKET_UDP_CLIENT_GET_NEWGRFS)
183+
p = DataPacket(0, const.PACKET_UDP_CLIENT_GET_NEWGRFS)
206184
p.send_uint8(len(grfs))
207185
for grf in grfs:
208186
p.send_something('4s16s', grf)
@@ -212,7 +190,7 @@ def getGRFInfo(self, grfs):
212190
LOG.debug("unable to receive UDP packet")
213191
return None
214192
newgrfs = []
215-
if p.command == PACKET_UDP_SERVER_NEWGRFS:
193+
if p.command == const.PACKET_UDP_SERVER_NEWGRFS:
216194
reply_count = p.recv_uint8()
217195
for i in range(0, reply_count):
218196
[grfid, md5sum] = p.recv_something('4s16s')
@@ -225,18 +203,18 @@ def getGRFInfo(self, grfs):
225203

226204
return newgrfs
227205
else:
228-
LOG.error("unexpected reply on PACKET_UDP_CLIENT_GET_NEWGRFS: %d" % (p.command))
206+
LOG.error("unexpected reply on const.PACKET_UDP_CLIENT_GET_NEWGRFS: %d" % (p.command))
229207

230208
def getCompanyInfo(self):
231-
self.sendMsg_UDP(PACKET_UDP_CLIENT_DETAIL_INFO)
209+
self.sendMsg_UDP(const.PACKET_UDP_CLIENT_DETAIL_INFO)
232210
p = self.receiveMsg_UDP(True)
233211
if p is None:
234212
return None
235-
if p.command == PACKET_UDP_SERVER_DETAIL_INFO:
213+
if p.command == const.PACKET_UDP_SERVER_DETAIL_INFO:
236214
info_version = p.recv_uint8()
237215
player_count = p.recv_uint8()
238216

239-
if info_version == NETWORK_COMPANY_INFO_VERSION or info_version == 4:
217+
if info_version == const.NETWORK_COMPANY_INFO_VERSION or info_version == 4:
240218
companies = []
241219

242220
for i in range(0, player_count):
@@ -284,26 +262,26 @@ def getCompanyInfo(self):
284262
ret.spectators = players
285263
return ret
286264
else:
287-
LOG.error("unsupported NETWORK_COMPANY_INFO_VERSION: %d. supported version: %d" % (info_version, NETWORK_COMPANY_INFO_VERSION))
265+
LOG.error("unsupported NETWORK_COMPANY_INFO_VERSION: %d. supported version: %d" % (info_version, const.NETWORK_COMPANY_INFO_VERSION))
288266
else:
289-
LOG.error("unexpected reply on PACKET_UDP_CLIENT_DETAIL_INFO: %d" % (command))
267+
LOG.error("unexpected reply on const.PACKET_UDP_CLIENT_DETAIL_INFO: %d" % (command))
290268
def getTCPCompanyInfo(self):
291-
self.sendMsg_TCP(PACKET_CLIENT_COMPANY_INFO)
269+
self.sendMsg_TCP(const.PACKET_CLIENT_COMPANY_INFO)
292270
p = self.receiveMsg_TCP(True)
293271
if res is None:
294272
return None
295-
if p.command == PACKET_SERVER_COMPANY_INFO:
273+
if p.command == const.PACKET_SERVER_COMPANY_INFO:
296274
[info_version, player_count] = p.recv_something('BB')
297-
if info_version == NETWORK_COMPANY_INFO_VERSION or info_version == 4: #4 and 5 are the same:
275+
if info_version == const.NETWORK_COMPANY_INFO_VERSION or info_version == 4: #4 and 5 are the same:
298276
companies = []
299277
firsttime = True
300278
for i in range(0, player_count):
301279
if not firsttime:
302280
p = self.receiveMsg_TCP(True)
303281
if p is None:
304282
return None
305-
if p.command != PACKET_SERVER_COMPANY_INFO:
306-
LOG.error("unexpectged reply on PACKET_CLIENT_COMPANY_INFO: %d" % p.command)
283+
if p.command != const.PACKET_SERVER_COMPANY_INFO:
284+
LOG.error("unexpectged reply on const.PACKET_CLIENT_COMPANY_INFO: %d" % p.command)
307285
return None
308286
[info_version, player_count] = p.recv_something('BB')
309287
firsttime = False
@@ -323,12 +301,12 @@ def getTCPCompanyInfo(self):
323301
companies.append(company)
324302
return companies
325303
else:
326-
LOG.error("unknown company info version %d, supported: %d" % (info_version, NETWORK_COMPANY_INFO_VERSION))
304+
LOG.error("unknown company info version %d, supported: %d" % (info_version, const.NETWORK_COMPANY_INFO_VERSION))
327305
else:
328-
LOG.error("unexpected reply on PACKET_CLIENT_COMPANY_INFO: %d" % (command))
306+
LOG.error("unexpected reply on const.PACKET_CLIENT_COMPANY_INFO: %d" % (command))
329307

330308
def getGameInfo(self, encode_grfs=False, short=False):
331-
self.sendMsg_UDP(PACKET_UDP_CLIENT_FIND_SERVER)
309+
self.sendMsg_UDP(const.PACKET_UDP_CLIENT_FIND_SERVER)
332310
result = self.receiveMsg_UDP()
333311
if result is None:
334312
LOG.debug("unable to receive UDP packet")
@@ -441,7 +419,7 @@ def packetTest(self):
441419
format_payload = '15s80sbb33s'
442420
payload = struct.pack(format_payload, serverversion, playername, playas, netlang, uniqueid)
443421

444-
self.sendMsg_TCP(PACKET_CLIENT_JOIN, payload)
422+
self.sendMsg_TCP(const.PACKET_CLIENT_JOIN, payload)
445423

446424
def createPacketHeader(self, command, payload):
447425
return struct.pack(self.header_format, self.header_size + len(payload), command)
@@ -478,7 +456,7 @@ def receiveMsg_UDP(self, datapacket = False):
478456
LOG.error('receiveMsg_UDP error: '+str(e))
479457
errorMsg = StringIO.StringIO()
480458
traceback.print_exc(file=errorMsg)
481-
logging.error(errorMsg.getvalue())
459+
LOG.error(errorMsg.getvalue())
482460
if not str(e) in self.errors:
483461
self.errors.append(str(e))
484462

@@ -492,9 +470,9 @@ def receiveMsg_TCP(self, datapacket = False):
492470
note += "HEADER SEGMENTED INTO %s SEGMENTS!" % readcounter
493471

494472
size, command = self.parsePacketHeader(data)
495-
if not command in (PACKET_SERVER_FRAME, PACKET_SERVER_SYNC):
496-
if command in packet_names:
497-
LOG.debug("received size: %d, command: %s (%d)"% (size, packet_names[command], command))
473+
if not command in (const.PACKET_SERVER_FRAME, const.PACKET_SERVER_SYNC):
474+
if command in const.packet_names:
475+
LOG.debug("received size: %d, command: %s (%d)"% (size, const.packet_names[command], command))
498476
else:
499477
LOG.debug("received size: %d, command: %d"% (size, command))
500478
size -= self.header_size # remove size of the header ...
@@ -516,10 +494,5 @@ def receiveMsg_TCP(self, datapacket = False):
516494
#content = content[0]
517495

518496
#LOG.debug(size, command, content)
519-
def dateToYMD(self, date):
520-
if date == 0:
521-
return (0, 0, 0)
522-
ymddate = datetime.date.fromordinal(date - 365)
523-
return (ymddate.year, ymddate.month, ymddate.day)
524497

525498

File renamed without changes.
File renamed without changes.

ottd_savegame.py renamed to openttd/savegame.py

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/bin/env python
22
# reading openttd .sav files with python
33
# made by yorickvanpelt {AT} gmail {DOT} com
4-
from struct_zerostrings import unpackFromExt, packExt
5-
from ottd_constants import saveload_chunk_types
4+
import struct
5+
from constants import saveload_chunk_types
66
import array
77

88
class LoadException(Exception):
@@ -27,7 +27,13 @@ def read_something(self, type):
2727
@rtype: list
2828
@returns: list with unpacked stuff
2929
"""
30-
ret, size = unpackFromExt(type, self.data[self.offset:])
30+
try:
31+
s = struct.Struct(type)
32+
size = s.size
33+
ret = s.unpack(self.data[self.offset:self.offset+size])
34+
except AttributeError:
35+
size = struct.calcsize(type)
36+
ret = struct.unpack(type, self.data[self.offset:self.offset+size])
3137
self.offset += size
3238
return ret
3339
def write_something(self, type, something):
@@ -38,14 +44,17 @@ def write_something(self, type, something):
3844
@param something: list with stuff to be packed
3945
@type something: list
4046
"""
41-
buf = packExt(type, *something)
42-
self.size += len(buf)
47+
try:
48+
s = struct.Struct(type)
49+
buf = s.pack(*something)
50+
size = s.size
51+
except AttributeError:
52+
buf = struct.pack(type, *something)
53+
size = len(buf)
54+
self.size += size
4355
self.data += buf
44-
def read_str(self, len=None):
45-
if not len is None:
46-
return self.read_something(str(len)+'s')[0]
47-
else:
48-
return self.read_something('z')[0]
56+
def read_str(self, len):
57+
return self.read_something(str(len)+'s')[0]
4958
def read_uint8(self):
5059
return self.read_something('>B')[0]
5160
def read_int8(self):
@@ -111,7 +120,7 @@ def read_OTTDSimpleGamma(self):
111120
return i
112121
def read_array(self, format, number):
113122
a = array.array(format)
114-
end_offs = self.offset + number
123+
end_offs = self.offset + struct.calcsize(format) * number
115124
a.fromstring(self.data[self.offset:end_offs])
116125
self.offset = end_offs
117126
return a.tolist()

ottd-client.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
#!/bin/env python
2+
import sys
23
import os
34
import os.path
45
import StringIO
56
import traceback
67
import time
78
from log import LOG
8-
from ottd_lib import M_TCP, M_UDP, M_BOTH, Client
9+
from openttd.client import M_TCP, M_UDP, M_BOTH, Client
910
from ottd_config import config, LoadConfig
1011
from struct_zerostrings import packExt, unpackExt, unpackFromExt
1112
from ottd_client_event import IngameChat, IRCPublicChat, IRCPrivateChat, IRCPrivateNoticeChat, Broadcast, IngameToIRC, InternalCommand, IRCPublicActionChat, IRCPrivateActionChat, IRCToIngame
1213

1314
import plugins
14-
import ottd_constants as const
15+
import openttd.constants as const
16+
17+
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "lib"))
1518

1619
SVNREVISION = "$Rev$"
1720

@@ -545,7 +548,7 @@ def joinGame(self):
545548
offset += size2
546549

547550
if command2 == const.MAP_PACKET_START:
548-
LOG.info("starting downloading map!")
551+
LOG.info("start downloading map!")
549552
[framecounter], size2 = unpackFromExt('I', content[offset:])
550553
offset += size2
551554

ottd-gameinfo.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/bin/env python
22
# made by thomas {AT} thomasfischer {DOT} biz
3-
from ottd_lib import *
4-
from ottd_grfs import GrfDB
3+
from openttd.client import Client, M_UDP
4+
from openttd.grfdb import GrfDB
5+
import openttd.date
6+
import sys
57

68
def printUsage():
79
print "usage: %s <ip:port>" % sys.argv[0]
@@ -24,6 +26,8 @@ def main():
2426
if not gi is None:
2527
for k in ["companies_max","companies_on", "spectators_max", "server_name", "server_revision", "server_lang", "use_password", "clients_max", "clients_on", "spectators_on", "map_name", "map_width", "map_height", "map_set", "dedicated"]:
2628
print "%20s: %s" % (k, getattr(gi, k))
29+
print "%20s: %s" % ("game_date", str(openttd.date.OpenTTDDate(ottddate=gi.game_date).toDate()))
30+
print "%20s: %s" % ("start_date", str(openttd.date.OpenTTDDate(ottddate=gi.start_date).toDate()))
2731
else:
2832
return
2933
if gi.companies_on > 0:
@@ -36,7 +40,7 @@ def main():
3640
cis = client.getTCPCompanyInfo()
3741
using_tcp = True
3842
except:
39-
cisi = client.getCompanyInfo(True)
43+
cisi = client.getCompanyInfo()
4044
cis = cisi.companies
4145
using_tcp = False
4246
else:
@@ -54,7 +58,7 @@ def main():
5458
print "%20s:"%("Clients")
5559
for cli in ci.clients:
5660
if cli.join_date > 0:
57-
jd = client.dateToYMD(cli.join_date)
61+
jd = openttd.date.OpenTTDDate(ottddate=cli.join_date).toYMD()
5862
else:
5963
jd = [0,0,0]
6064
print "%30s, joined %d - %d - %d" % (cli.client_name, jd[2], jd[1], jd[0])

ottd-rcon.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#!/bin/env python
22
# made by yorickvanpelt {AT} gmail {DOT} com
33
# ottd_lib by thomas {AT} thomasfischer {DOT} biz
4-
from ottd_lib import *
4+
from openttd.client import *
5+
import openttd.constants as const
56
from struct_zerostrings import packExt, unpackExt, unpackFromExt
67

7-
import ottd_constants as const
8-
98
if platform.system() == 'Windows':
109
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_api_reference.asp
1110
# for information on Windows APIs.

0 commit comments

Comments
 (0)