server.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. local NetServer = extend(app.net.core)
  2. NetServer.signatures = app.net.signatures.server
  3. NetServer.receive = {}
  4. NetServer.receive['default'] = f.empty
  5. NetServer.receive[app.net.messages.join] = function(self, event)
  6. local pid = self.peerToPlayer[event.peer]
  7. ctx.players:get(pid).username = event.data.username
  8. self:send(app.net.messages.join, event.peer, {id = pid})
  9. self:emit(app.net.events.join, {id = pid, username = event.data.username})
  10. self:emit(app.net.events.chat, {message = '{white}' .. event.data.username .. ' has joined!'})
  11. self:snapshot(event.peer)
  12. end
  13. NetServer.receive[app.net.messages.leave] = function(self, event) self:disconnect(event) end
  14. NetServer.receive[app.net.messages.class] = function(self, event)
  15. self:emit(app.net.events.class, {id = self.peerToPlayer[event.peer], class = event.data.class, team = event.data.team})
  16. end
  17. NetServer.receive[app.net.messages.input] = function(self, event)
  18. ctx.players:get(self.peerToPlayer[event.peer]):trace(event.data, event.peer:round_trip_time())
  19. end
  20. NetServer.receive[app.net.messages.chat] = function(self, event)
  21. local pid = self.peerToPlayer[event.peer]
  22. local username = ctx.players:get(pid).username
  23. local color = ctx.players:get(pid).team == 0 and 'purple' or 'orange'
  24. local message = event.data.message
  25. if message:sub(1, 1) == '/' then
  26. local data = {}
  27. for word in string.gmatch(message, '([^ ]+)') do
  28. table.insert(data, word)
  29. end
  30. local function reply(message) self:send(app.net.events.chat, event.peer, {message = '{red}' .. message}) end
  31. local handlers = {
  32. ['/restart'] = function(data)
  33. if username ~= ctx.owner then return reply('permission denied') end
  34. ctx.event:emit('game.restart')
  35. reply('game restarted')
  36. end,
  37. ['/kick'] = function(data)
  38. if username ~= ctx.owner then return reply('permission denied') end
  39. if not data[2] or #data[2] == 0 then return reply('who are we kicking?') end
  40. if data[2] == ctx.owner then return reply('don\'t be so masokicktic! *pats on back*') end
  41. local player, peer
  42. for i = 1, ctx.players.max do
  43. if ctx.players:get(i).username == data[2] then player = i break end
  44. end
  45. if not player then return self:send(app.net.events.chat, event.peer, {message = '{red}couldn\'t find player "' .. data[2] .. '"'}) end
  46. for i = 1, ctx.players.max do
  47. local p = self.host:get_peer(i)
  48. if self.peerToPlayer[p] == player then peer = p break end
  49. end
  50. if not peer then return self:send(app.net.events.chat, event.peer, {message = '{red}"' .. data[2] .. '" doesn\'t seem to be connected'}) end
  51. self:disconnect({peer = peer, reason = 'kicked'})
  52. end,
  53. ['/roll'] = function(data)
  54. self:emit(app.net.events.chat, {message = '{red}' .. username .. ' rolled {green}' .. love.math.random(1, 100)})
  55. end,
  56. ['/bjorn'] = function(data)
  57. self:emit(app.net.events.chat, {message = '{purple}-_-'})
  58. end,
  59. default = function(data)
  60. self:send(app.net.events.chat, event.peer, {message = '{red}unknown command "' .. data[1]:sub(2) .. '"'})
  61. end
  62. }
  63. handlers['/reset'] = handlers['/restart']
  64. handlers['/refresh'] = handlers['/restart']
  65. handlers['/sakujo'] = handlers['/kick']
  66. return (handlers[data[1]] or handlers.default)(data)
  67. end
  68. self:emit(app.net.events.chat, {message = '{' .. color .. '}' .. username .. '{white}: ' .. message})
  69. end
  70. function NetServer:init()
  71. self.other = app.net.client
  72. self:listen(6061)
  73. self.peerToPlayer = {}
  74. self.eventBuffer = {}
  75. self.importantEventBuffer = {}
  76. ctx.event:on('game.quit', function(data)
  77. self:quit()
  78. end)
  79. app.net.core.init(self)
  80. end
  81. function NetServer:quit()
  82. if self.host then
  83. for i = 1, ctx.players.max do
  84. if self.host:get_peer(i) then self.host:get_peer(i):disconnect_now() end
  85. end
  86. self.host:flush()
  87. end
  88. self.host = nil
  89. end
  90. function NetServer:connect(event)
  91. self.peerToPlayer[event.peer] = self:nextPlayerId()
  92. event.peer:timeout(0, 0, 3000)
  93. event.peer:ping_interval(100)
  94. event.peer:ping()
  95. end
  96. function NetServer:disconnect(event)
  97. local pid = self.peerToPlayer[event.peer]
  98. local username = ctx.players:get(pid).username
  99. local reason = event.reason or 'left'
  100. self:emit(app.net.events.chat, {message = '{white}' .. username .. ' has left (' .. reason .. ')'})
  101. self:emit(app.net.events.leave, {id = pid, reason = reason})
  102. self.peerToPlayer[event.peer] = nil
  103. event.peer:disconnect_now()
  104. if username == ctx.owner then
  105. ctx.event:emit('game.quit')
  106. end
  107. end
  108. function NetServer:send(msg, peer, data)
  109. self.outStream:clear()
  110. self:pack(msg, data)
  111. peer:send(tostring(self.outStream))
  112. end
  113. function NetServer:emit(evt, data)
  114. if not self.host then return end
  115. local buffer = self.signatures[evt].important and self.importantEventBuffer or self.eventBuffer
  116. table.insert(buffer, {evt, data})
  117. ctx.event:emit(evt, data)
  118. end
  119. function NetServer:sync()
  120. if not self.host then return end
  121. if #self.importantEventBuffer > 0 then
  122. self.outStream:clear()
  123. while #self.importantEventBuffer > 0 do
  124. self:pack(unpack(self.importantEventBuffer[1]))
  125. table.remove(self.importantEventBuffer, 1)
  126. end
  127. self.host:broadcast(tostring(self.outStream), 0, 'reliable')
  128. end
  129. if #self.eventBuffer > 0 then
  130. self.outStream:clear()
  131. while #self.eventBuffer > 0 do
  132. self:pack(unpack(self.eventBuffer[1]))
  133. table.remove(self.eventBuffer, 1)
  134. end
  135. self.host:broadcast(tostring(self.outStream), 1, 'unreliable')
  136. end
  137. end
  138. function NetServer:snapshot(peer)
  139. local players = {}
  140. for id = 1, ctx.players.max do
  141. local p = ctx.players:get(id)
  142. if #p.username > 0 and id ~= self.peerToPlayer[peer] then
  143. table.insert(players, {
  144. id = id,
  145. username = p.username,
  146. class = p.class and p.class.id or 0,
  147. team = p.team or 0,
  148. })
  149. end
  150. end
  151. self:send(app.net.messages.snapshot, peer, {tick = tick, map = 'testArena', ['players'] = players})
  152. end
  153. function NetServer:nextPlayerId()
  154. for i = 1, ctx.players.max do
  155. if #ctx.players:get(i).username == 0 then return i end
  156. end
  157. end
  158. return NetServer