/
serverNet.py
130 lines (115 loc) · 5.47 KB
/
serverNet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import sys
sys.path.append('..')
import sandbox
from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "notify-level-ITF-ServerNetwork debug")
from direct.directnotify.DirectNotify import DirectNotify
log = DirectNotify().newCategory("ITF-ServerNetwork")
import protocol
import shipComponents
import universals
import shipSystem
class AccountComponent(object):
address = None
class NetworkSystem(sandbox.UDPNetworkSystem):
def init2(self):
self.accept("broadcastData", self.broadcastData)
self.accept("confirmPlayerStations", self.confirmPlayerStations)
self.accept('playerDisconnected', self.playerDisconnected)
self.activePlayers = [] # PlayerComponent
self.playerMap = {} # {Address: Shipid}
#self.shipMap = {} # {ShipID: {CONSOL: Netaddress}}
#self.accept("shipGenerated", self.shipGenerated)
if universals.runServer and not universals.runClient:
sandbox.base.taskMgr.doMethodLater(0.2, self.sendShipUpdates, 'shipUpdates')
def processPacket(
self, msgID, remotePacketCount,
ack, acks, hashID, serialized, address
):
#If not in our protocol range then we just reject
if msgID < 0 or msgID > 200:
return
data = protocol.readProto(msgID, serialized)
if data is None and msgID != protocol.LOGIN:
log.warning("Package reading error: " + str(msgID) + " " + serialized)
return
#Order of these will need to be optimized later
if msgID == protocol.LOGIN:
#TODO, if connection previously existed, reconnect
#TODO: send current mission status.
#TODO: Move ship select to separate function
ackDatagram = protocol.shipClasses(shipSystem.shipClasses)
self.sendData(ackDatagram, address)
ackDatagram = protocol.playerShipStations()
self.sendData(ackDatagram, address)
entity = sandbox.createEntity()
component = AccountComponent()
component.address = address
entity.addComponent(component)
self.activeConnections[component.address] = component
elif msgID == protocol.REQUEST_CREATE_SHIP:
sandbox.send('spawnShip', [data.name, data.className, True])
elif msgID == protocol.REQUEST_STATIONS:
entity = sandbox.entities[data.ship[0].id]
#info = entity.getComponent(shipComponents.InfoComponent)
player = entity.getComponent(shipComponents.PlayerComponent)
stations = data.ship[0].stations
for stationName in universals.playerStations:
if getattr(player, stationName) != 0:
print "Resend ship select window"
sandbox.send('setPlayerStations', [address, data.ship[0].id, stations])
elif msgID == protocol.SET_THROTTLE:
sandbox.send('setThrottle', [self.playerMap[address], data])
elif msgID == protocol.SET_TARGET:
sandbox.send('setTarget', [self.playerMap[address], data])
'''if username not in accountEntities:
entity = sandbox.createEntity()
component = AccountComponent()
component.name = username
component.passwordHash = password
if not accountEntities:
component.owner = True
component.address = datagram.getAddress()
entity.addComponent(component)
accountEntities[username] = entity.id
log.info("New player " + username + " logged in.")
#
self.activePlayers.append(component)
self.activeConnections[component.address] = component
ackDatagram = protocol.loginAccepted(entity.id)
self.sendData(ackDatagram, datagram.getAddress())
#TODO: Send initial states?
#messenger.send("newPlayerShip", [component, entity])
else:
component = sandbox.entities[accountEntities[username]].getComponent(AccountComponent)
if component.passwordHash != password:
log.info("Player " + username + " has the wrong password.")
else:
component.connection = datagram.getConnection()
log.info("Player " + username + " logged in.")'''
def broadcastData(self, datagram):
# Broadcast data out to all activeConnections
#for accountID in accountEntities.items():
#sandbox.entities[accountID].getComponent()
for addr in self.activeConnections.keys():
self.sendData(datagram, addr)
def sendShipUpdates(self, task):
ships = sandbox.getSystem(shipSystem.ShipSystem).getPlayerShipEntities()
ships += sandbox.getEntitiesByComponentType(shipComponents.AIPilotComponent)
#self.broadcastData(protocol.sendShipUpdates(ships))
for ship in ships:
self.broadcastData(protocol.sendShipUpdates([ship]))
return task.again
def playerDisconnected(self, address):
try:
print "Removing", address, "from", self.playerMap
del self.playerMap[address]
except:
print address, "not in", self.playerMap
def confirmPlayerStations(self, netAddress, shipid, stations):
self.playerMap[netAddress] = shipid
datagram = protocol.confirmStations(shipid, stations)
self.sendData(datagram, netAddress)
class ClientComponent:
"""Theoretical component that stores which clients are
also tracking this entity as well as last update"""