@@ -11,6 +11,7 @@ local enet = require 'enet'
1111local math = require ' math'
1212local socket = require ' socket'
1313local log = core .import ' class.logger'
14+ local json = core .import ' class.parser.json'
1415local helper = core .import ' helper'
1516local packer = core .import ' external.packer'
1617local Client = core .import ' class.client'
@@ -43,14 +44,15 @@ local clients = setmetatable({ }, { __newindex = function (t, k, v) rawset(t, k,
4344local players = setmetatable ({ }, { __newindex = function (t , k , v ) rawset (t , k , v );clients_resort = true end })
4445
4546-- Constants
47+ local SEP = 29
4648local PENDING = - 1
4749local RELAY_WAIT_TIME = 1
4850local RELAY_MAX_COUNT = 10
4951local RELAY_CLIENT_ATTEMPTS = 5
5052local RELAY_MASTER_ATTEMPTS = 8
5153local MIN_PEER_TIMEOUT = 2000
5254local MAX_PEER_TIMEOUT = 4000
53- local NETRECORD_PATTERN = ' ([^' .. strchar (29 ) .. ' ]+)'
55+ local NETRECORD_PATTERN = ' ([^' .. strchar (SEP ) .. ' ]+)'
5456
5557-- Client message codes
5658local LOGIN = 1
@@ -64,6 +66,7 @@ local FLUSH = 1
6466local LIST = 2
6567local LINK = 3
6668local RELAY = 4
69+ local LOBBY = 6
6770
6871if os.getenv (' L2DF_MASTER' ) then
6972 masters [os.getenv (' L2DF_MASTER' )] = PENDING
211214local ClientEvents = { }
212215local ClientEventsMap = { }
213216
217+ local function ClientEventEmitter (event , ...)
218+ local handler = ClientEvents [ClientEventsMap [event ] or event ]
219+ if not handler then
220+ return false
221+ end
222+ for i = 3 , # handler do
223+ handler [i ](... )
224+ end
225+ return true
226+ end
227+
214228local MasterEvents = {
215229 -- Connected to master
216230 connect = function (self , manager , host , event )
@@ -219,9 +233,9 @@ local MasterEvents = {
219233 log :success (' Connected to master: %s' , host )
220234 master .peer :last_round_trip_time (50 )
221235 master .peer :ping ()
222- master .peer :send ( strformat (' %c%s%c%s' , LOGIN , manager .ip , 29 , manager .username ) )
223- master .peer :send ( strformat (' %c' , LIST ) )
236+ master .peer :send ( strformat (' %c%s%c%s' , LOGIN , manager .ip , SEP , manager .username ) )
224237 master .initialized = true
238+ ClientEventEmitter (' masterconnected' , master , event )
225239 end
226240 end ,
227241
@@ -245,6 +259,7 @@ local MasterEvents = {
245259 elseif not master .relayed then
246260 log :warn ' Lost connection to master.'
247261 end
262+ ClientEventEmitter (' masterdisconnected' , master , event )
248263 end
249264 end ,
250265
@@ -259,7 +274,7 @@ local MasterEvents = {
259274
260275 -- Request to link another peer
261276 [LINK ] = function (self , manager , host , event , payload )
262- local ip , name , private , public , port = itunpack (strgmatch (payload , NETRECORD_PATTERN ))
277+ local ip , id , name , private , public , port = itunpack (strgmatch (payload , NETRECORD_PATTERN ))
263278 -- Peers are under one NAT
264279 if public == ip then
265280 public , private = private , public
@@ -268,9 +283,10 @@ local MasterEvents = {
268283 local client = players [name ] or clients [Client :id (0 , e1 )] or clients [Client :id (0 , e2 )] or Client {
269284 events = ClientEvents ,
270285 emap = ClientEventsMap ,
286+ emitter = ClientEventEmitter ,
271287 cstate = ' punching' ,
272288 }
273- client .name = name
289+ client .uid , client . name = id , name
274290 if client :state () == ' connected' then
275291 return
276292 end
@@ -289,7 +305,17 @@ local MasterEvents = {
289305 if # lobbies == 1 and lobbies [1 ] == ' ' then
290306 lobbies [1 ] = nil
291307 end
292- print (' LOBBIES' , helper .dump (lobbies ))
308+ for i = 1 , # lobbies do
309+ lobbies [i ] = json :parse (lobbies [i ])
310+ end
311+ end ,
312+
313+ -- Client was added to lobby
314+ [LOBBY ] = function (self , manager , host , event , payload )
315+ if manager .lobbyid ~= payload then
316+ manager .lobbyid = payload
317+ ClientEventEmitter (' masterlobby' , master , event , payload )
318+ end
293319 end ,
294320
295321 -- Reply from master to relay peers
@@ -299,6 +325,7 @@ local MasterEvents = {
299325 local client = clients [Client .id (event , channel )] or Client {
300326 events = ClientEvents ,
301327 emap = ClientEventsMap ,
328+ emitter = ClientEventEmitter ,
302329 name = name ,
303330 peer = event .peer ,
304331 channel = event .channel ,
@@ -313,6 +340,7 @@ local MasterEvents = {
313340 -- Drop all connections (leaving lobby)
314341 [FLUSH ] = function (self , manager , host , event , payload )
315342 log :info (' FLUSH all connections' )
343+ manager .lobbyid = nil
316344 for id , client in pairs (clients ) do
317345 client :disconnect ()
318346 setClient (id , client .name )
@@ -405,7 +433,8 @@ local Manager = { ip = '127.0.0.1' }
405433 -- @param [opt] string username
406434 -- @return l2df.manager.network
407435 function Manager :login (username )
408- username = username or self :initSocket ().username
436+ self :initSocket ()
437+ username = username or self .username
409438 self .username = assert (type (username ) == ' string' and username , ' Username is required for NetworkManager' )
410439 self .ip = discoverIP () or ' 127.0.0.1'
411440 for id , c in pairs (clients ) do
@@ -421,6 +450,7 @@ local Manager = { ip = '127.0.0.1' }
421450 --- Disconnects from all registered masters
422451 -- @return l2df.manager.network
423452 function Manager :logout ()
453+ self .lobbyid = nil
424454 for host , master in pairs (masters ) do
425455 if master ~= PENDING then
426456 if master .relayed then
@@ -445,6 +475,36 @@ local Manager = { ip = '127.0.0.1' }
445475 return true
446476 end
447477
478+ --- Create new lobby
479+ -- @return boolean
480+ function Manager :host ()
481+ if not self :isReady () then
482+ return false
483+ end
484+ Masters_broadcast (' %c' , FIND )
485+ return true
486+ end
487+
488+ local function getLobbies ()
489+ return lobbies
490+ end
491+
492+ ---
493+ -- @param [opt] number count
494+ -- @param [opt] boolean refresh
495+ -- @return function
496+ function Manager :list (count , refresh )
497+ if refresh then
498+ lobbies = nil
499+ end
500+ if count then
501+ Masters_broadcast (' %c%d' , LIST , count )
502+ else
503+ Masters_broadcast (' %c' , LIST )
504+ end
505+ return getLobbies
506+ end
507+
448508 --- Register new network event
449509 -- @param string name
450510 -- @param string format
@@ -470,8 +530,9 @@ local Manager = { ip = '127.0.0.1' }
470530 function Manager :broadcast (event , ...)
471531 event = event and ClientEventsMap [event ] or 0
472532 local format = ClientEvents [event ]
473- if not (format and self :isConnected ()) then return false end
474-
533+ if not (format and self :isConnected ()) then
534+ return false
535+ end
475536 local result = true
476537 for _ , client in pairs (clients ) do
477538 result = client :rawsend (format [1 ], event , ... ) and result
@@ -533,6 +594,7 @@ local Manager = { ip = '127.0.0.1' }
533594 client = relay_remap [eid ] or clients [eid ] or masters [endpoint ] or Client {
534595 events = ClientEvents ,
535596 emap = ClientEventsMap ,
597+ emitter = ClientEventEmitter ,
536598 peer = event .peer ,
537599 channel = event .channel ,
538600 }
@@ -637,7 +699,8 @@ local Manager = { ip = '127.0.0.1' }
637699 -- Relay connection established
638700 elseif c :state () == ' relay-connecting' then
639701 clients_resort = true
640- setClient (c :id (), name , c :connected (c .event ))
702+ setClient (c :id (), name , c )
703+ c :connected (c .event )
641704 c :verify (c .event )
642705 pending_relays [name ] = nil
643706
0 commit comments