@@ -6,8 +6,100 @@ var taken_nicknames=[];
66
77var server = net . createServer ( function ( conn ) {
88 var currentLobby = - 1 , nickname = null , running = false ; //persistent
9- conn . on ( "data" , connectionLobbyDataListener ) ;
10- conn . on ( "end" , function ( ) {
9+ var onEndFunction ;
10+ conn . on ( "data" , ( function ( ) {
11+ var databuffer = "" , wasInGame = false ; //persistent
12+ return function ( data ) {
13+ var line , idx ;
14+ if ( currentLobby != - 1 && lobbies [ lobbyIndex ( currentLobby ) ] . players . length == 2 ) {
15+ wasInGame = true ;
16+ return ; //the other listener will take over
17+ }
18+ if ( wasInGame ) {
19+ currentLobby = - 1 ;
20+ wasInGame = false ;
21+ }
22+ databuffer += data ;
23+ while ( databuffer . length && ( idx = databuffer . indexOf ( "\n" ) ) != - 1 ) {
24+ line = databuffer . slice ( 0 , idx ) ;
25+ databuffer = databuffer . slice ( idx + 1 ) ;
26+ if ( line . match ( / ^ n i c k / ) ) {
27+ nickname = line . slice ( 5 ) ;
28+ if ( taken_nicknames . indexOf ( nickname ) != - 1 ) {
29+ conn . write ( "error Nickname is already taken\n" ) ;
30+ nickname = null ;
31+ continue ;
32+ }
33+ taken_nicknames . push ( nickname ) ;
34+ conn . write ( "nick_ok\n" ) ;
35+ continue ;
36+ }
37+ if ( nickname == undefined ) {
38+ conn . write ( "error Can only send a \"nick\" line while no nickname set\n" ) ;
39+ continue ;
40+ }
41+ if ( line == "list_lobbies" ) {
42+ conn . write ( "list_lobbies " + lobbies . length + "\n" ) ;
43+ lobbies . forEach ( function ( lob ) {
44+ conn . write ( "lobby " + lob . id + " " + lob . players . length + " " + lob . name + "\n" ) ;
45+ } ) ;
46+ } else if ( line . match ( / ^ j o i n _ l o b b y / ) ) {
47+ var choice = + line . slice ( 11 ) , chosenLobby ;
48+ if ( isNaN ( choice ) || choice < 0 || choice % 1 != 0 || ( chosenLobby = lobbyIndex ( choice ) , ( chosenLobby == - 1 || chosenLobby == currentLobby ) ) ) {
49+ conn . write ( "error Invalid lobby\n" ) ;
50+ continue ;
51+ }
52+ if ( chosenLobby == undefined ) chosenLobby = lobbyIndex ( choice ) ;
53+ if ( currentLobby != - 1 ) {
54+ idx = lobbyIndex ( currentLobby ) ;
55+ if ( idx != - 1 ) {
56+ if ( lobbies [ idx ] . running ) {
57+ conn . write ( "error Cannot join a lobby while still playing one\n" ) ;
58+ continue ;
59+ }
60+ lobbies . splice ( idx , 1 ) ;
61+ }
62+ }
63+ lobbies [ chosenLobby ] . players . push ( [ nickname , conn ] ) ;
64+ startGame ( chosenLobby , databuffer ) ;
65+ } else if ( line . match ( / ^ c r e a t e _ l o b b y / ) ) {
66+ var lname = line . slice ( 13 ) ;
67+ if ( lobbies . filter ( function ( l ) { return l . name == lname ; } ) . length != 0 ) {
68+ conn . write ( "error A lobby already exists with that name\n" ) ;
69+ continue ;
70+ }
71+ if ( currentLobby != - 1 ) {
72+ idx = lobbyIndex ( currentLobby ) ;
73+ if ( idx != - 1 ) {
74+ if ( lobbies [ idx ] . running ) {
75+ conn . write ( "error Cannot create a lobby while still playing one\n" ) ;
76+ continue ;
77+ }
78+ lobbies . splice ( idx , 1 ) ;
79+ }
80+ }
81+ currentLobby = uniqid ( ) ;
82+ lobbies . push ( { id :currentLobby , name :lname , players :[ [ nickname , conn ] ] } ) ;
83+ conn . write ( "create_lobby_ok\n" ) ;
84+ } else if ( line == "my_lobby" ) {
85+ if ( currentLobby == - 1 ) conn . write ( "my_lobby\n" ) ;
86+ else conn . write ( "my_lobby " + lobbies [ lobbyIndex ( currentLobby ) ] . name + "\n" ) ;
87+ } else if ( line . match ( / ^ l o b b y _ i n f o / ) ) {
88+ var which = + line . slice ( 11 ) , whichLobby ;
89+ if ( isNaN ( which ) || which < 0 || which % 1 != 0 || ( chosenLobby = lobbyIndex ( which ) ) ) {
90+ conn . write ( "error Invalid lobby\n" ) ;
91+ continue ;
92+ }
93+ if ( whichLobby == undefined ) chosenLobby = lobbyIndex ( which ) ;
94+ conn . write ( "lobby_info " + lobbies [ chosenLobby ] . players . length + "\n" ) ;
95+ lobbies [ chosenLobby ] . players . forEach ( function ( pl ) { conn . write ( "player " + pl [ 0 ] + "\n" ) ; } ) ;
96+ } else {
97+ conn . write ( "error Invalid command sent (" + ( line . length <= 10 ?"" :"starting with " ) + "\"" + line . slice ( 0 , 10 ) + "\")\n" ) ;
98+ }
99+ }
100+ } ;
101+ } ) ( ) ) ;
102+ onEndFunction = function ( ) {
11103 if ( nickname != null ) taken_nicknames . splice ( taken_nicknames . indexOf ( nickname ) , 1 ) ;
12104 if ( currentLobby != - 1 ) {
13105 var idx = lobbyIndex ( currentLobby ) ;
@@ -16,6 +108,11 @@ var server=net.createServer(function(conn){
16108 }
17109 lobbies . splice ( idx , 1 ) ;
18110 }
111+ } ;
112+ conn . on ( "end" , onEndFunction ) ;
113+ conn . on ( "error" , function ( err ) {
114+ console . log ( err ) ;
115+ onEndFunction ( ) ;
19116 } ) ;
20117} ) ;
21118server . listen ( 18632 , function ( ) {
@@ -35,117 +132,65 @@ uniqid=(function(){
35132
36133function fill_array ( len , val ) { var a = new Array ( len ) ; for ( ; len -- > 0 ; a [ len ] = ( typeof val == "function" ?val ( len ) :val ) ) ; return a ; }
37134
38- function connectionLobbyDataListener ( data ) {
39- var databuffer = "" ; //persistent
40- var line , idx ;
41- databuffer += data ;
42- while ( databuffer . length && ( idx = databuffer . indexOf ( "\n" ) ) ) {
43- line = databuffer . slice ( 0 , idx ) ;
44- databuffer = databuffer . slice ( idx + 1 ) ;
45- if ( line . match ( / ^ n i c k / ) ) {
46- nickname = line . slice ( 5 ) ;
47- if ( taken_nicknames . indexOf ( nickname ) != - 1 ) {
48- conn . write ( "error Nickname is already taken\n" ) ;
49- nickname = null ;
50- continue ;
51- }
52- taken_nicknames . push ( nickname ) ;
53- conn . write ( "nick_ok\n" ) ;
54- continue ;
55- }
56- if ( nickname == undefined ) {
57- conn . write ( "error Can only send a \"nick\" line while no nickname set\n" ) ;
58- continue ;
59- }
60- if ( line == "list_lobbies" ) {
61- conn . write ( "list_lobbies " + lobbies . length + "\n" ) ;
62- lobbies . forEach ( function ( lob ) {
63- conn . write ( "lobby " + lob . id + " " + lob . players . length + " " + lob . name + "\n" ) ;
64- } ) ;
65- } else if ( line . match ( / ^ j o i n _ l o b b y / ) ) {
66- var choice = + line . slice ( 11 ) , chosenLobby ;
67- if ( isNaN ( choice ) || choice < 0 || choice % 1 != 0 || ( chosenLobby = lobbyIndex ( choice ) , ( chosenLobby == - 1 || chosenLobby == currentLobby ) ) ) {
68- conn . write ( "error Invalid lobby\n" ) ;
69- continue ;
70- }
71- if ( chosenLobby == undefined ) chosenLobby = lobbyIndex ( choice ) ;
72- if ( currentLobby != - 1 ) {
73- idx = lobbyIndex ( currentLobby ) ;
74- if ( idx != - 1 ) {
75- if ( lobbies [ idx ] . running ) {
76- conn . write ( "error Cannot join a lobby while still playing one\n" ) ;
135+
136+ var adjacencyMatrix = [ [ 2 , 6 , 4 , 5 ] , [ 3 , 6 , 1 , 5 ] , [ 4 , 6 , 2 , 5 ] , [ 6 , 1 , 3 , 5 ] , [ 4 , 3 , 2 , 1 ] , [ 2 , 3 , 4 , 1 ] ] ,
137+ rotatingFromToGivesRelRot = [ [ NaN , 0 , NaN , 0 , 2 , 0 ] , [ 0 , NaN , 0 , NaN , 1 , 1 ] , [ NaN , 0 , NaN , 0 , 0 , 2 ] , [ 0 , NaN , 0 , NaN , 3 , 3 ] , [ 2 , 3 , 0 , 1 , NaN , NaN ] , [ 0 , 3 , 2 , 1 , NaN , NaN ] ] ,
138+ oppositeFace = [ 3 , 4 , 1 , 2 , 6 , 5 ] ;
139+
140+ function getCubeFace ( cube , side , rot ) {
141+ var face = cube [ side - 1 ] . join ( "" ) ;
142+ return face . slice ( rot % 4 ) + face . slice ( 0 , rot % 4 ) ;
143+ }
144+
145+ function startGame ( lobbyIdx ) {
146+ var lob = lobbies [ lobbyIdx ] , conn = [ lob . players [ 0 ] [ 1 ] , lob . players [ 1 ] [ 1 ] ] ; //lob is a reference
147+ var connectionGameDataListenerFactory = function ( conni ) {
148+ return function ( data ) {
149+ var databuffer = "" ; //persistent
150+ var line , idx ;
151+ databuffer += data ;
152+ while ( databuffer . length && ( idx = databuffer . indexOf ( "\n" ) ) ) {
153+ line = databuffer . slice ( 0 , idx ) ;
154+ databuffer = databuffer . slice ( idx + 1 ) ;
155+ if ( line == "quit_game" ) {
156+ conn [ 1 - conni ] . write ( "other_player_quit_game\n" )
157+ lobbies . splice ( lobbyIdx , 1 ) ;
158+ } else if ( line . match ( / ^ c l i c k / ) ) {
159+ var click = + line . slice ( 6 ) , cubeface , newface ;
160+ if ( lob . game . toMove != conni ) {
161+ conn [ conni ] . write ( "error Not your turn\n" ) ;
77162 continue ;
78163 }
79- lobbies . splice ( idx , 1 ) ;
80- }
81- }
82- lobbies [ chosenLobby ] . players . push ( [ nickname , conn ] ) ;
83- startGame ( chosenLobby ) ;
84- } else if ( line . match ( / ^ c r e a t e _ l o b b y / ) ) {
85- var lname = line . slice ( 13 ) ;
86- if ( lobbies . filter ( function ( l ) { return l . name == lname ; } ) . length != 0 ) {
87- conn . write ( "error A lobby already exists with that name\n" ) ;
88- continue ;
89- }
90- if ( currentLobby != - 1 ) {
91- idx = lobbyIndex ( currentLobby ) ;
92- if ( idx != - 1 ) {
93- if ( lobbies [ idx ] . running ) {
94- conn . write ( "error Cannot create a lobby while still playing one\n" ) ;
164+ if ( isNaN ( click ) || click < 0 || click > 3 || click % 1 != 0 ) {
165+ conn [ conni ] . write ( "error Invalid move\n" ) ;
95166 continue ;
96167 }
97- lobbies . splice ( idx , 1 ) ;
168+ cubeface = conni == 1 ?oppositeFace ( lob . player0at ) :lob . player0at ;
169+ lob . game . cube [ cubeface ] [ ( click + rot ) % 4 ] = 1 - lob . game . cube [ cubeface ] [ ( click + rot ) % 4 ] ;
170+ newface = adjacencyMatrix [ cubeface ] [ ( click + rot ) % 4 ] ;
171+ lob . rot = ( lob . rot + rotatingFromToGivesRelRot [ cubeface ] [ newface ] ) % 4 ;
172+ lob . game . player0at = newface ;
173+ } else {
174+ conn [ conni ] . write ( "error Invalid command sent (" + ( line . length <= 10 ?"" :"starting with " ) + "\"" + line . slice ( 0 , 10 ) + "\")\n" ) ;
98175 }
99176 }
100- currentLobby = uniqid ( ) ;
101- lobbies . push ( { id :currentLobby , name :lname , players :[ [ nickname , conn ] ] } ) ;
102- conn . write ( "create_lobby_ok\n" ) ;
103- } else if ( line == "my_lobby" ) {
104- if ( currentLobby == - 1 ) conn . write ( "my_lobby\n" ) ;
105- else conn . write ( "my_lobby " + lobbies [ lobbyIndex ( currentLobby ) ] . name + "\n" ) ;
106- } else if ( line . match ( / ^ l o b b y _ i n f o / ) ) {
107- var which = + line . slice ( 11 ) , whichLobby ;
108- if ( isNaN ( which ) || which < 0 || which % 1 != 0 || ( chosenLobby = lobbyIndex ( which ) ) ) {
109- conn . write ( "error Invalid lobby\n" ) ;
110- continue ;
111- }
112- if ( whichLobby == undefined ) chosenLobby = lobbyIndex ( which ) ;
113- conn . write ( "lobby_info " + lobbies [ chosenLobby ] . players . length + "\n" ) ;
114- lobbies [ chosenLobby ] . players . forEach ( function ( pl ) { conn . write ( "player " + pl [ 0 ] + "\n" ) ; } ) ;
115- } else {
116- conn . write ( "error Invalid command sent (" + ( line . length <= 10 ?"" :"starting with " ) + "\"" + line . slice ( 0 , 10 ) + "\")\n" ) ;
117- }
118- }
119- }
120-
121- function connectionGameDataListener ( data ) {
122- var databuffer = "" ; //persistent
123- var line , idx ;
124- databuffer += data ;
125- while ( databuffer . length && ( idx = databuffer . indexOf ( "\n" ) ) ) {
126- line = databuffer . slice ( 0 , idx ) ;
127- databuffer = databuffer . slice ( idx + 1 ) ;
128- if ( line . match ( / ^ n i c k / ) ) {
129- ;
130- } else {
131- conn . write ( "error Invalid command sent (" + ( line . length <= 10 ?"" :"starting with " ) + "\"" + line . slice ( 0 , 10 ) + "\")\n" ) ;
132- }
133- }
134- }
135-
136-
137- var adjacencyMatrix = [ [ 2 , 6 , 4 , 5 ] , [ 3 , 6 , 1 , 5 ] , [ 4 , 6 , 2 , 5 ] , [ 6 , 1 , 3 , 5 ] , [ 4 , 3 , 2 , 1 ] , [ 2 , 3 , 4 , 1 ] ] ,
138- rotatingFromToGivesRelRot = [ [ NaN , 0 , NaN , 0 , 2 , 0 ] , [ 0 , NaN , 0 , NaN , 1 , 1 ] , [ NaN , 0 , NaN , 0 , 0 , 2 ] , [ 0 , NaN , 0 , NaN , 3 , 3 ] , [ 2 , 3 , 0 , 1 , NaN , NaN ] , [ 0 , 3 , 2 , 1 , NaN , NaN ] ] ,
139- oppositesFaces = [ 3 , 4 , 1 , 2 , 6 , 5 ] ;
177+ } ;
178+ } ;
140179
180+ conn [ 0 ] . on ( "data" , connectionGameDataListenerFactory ( 0 ) ) ;
181+ conn [ 1 ] . on ( "data" , connectionGameDataListenerFactory ( 1 ) ) ;
141182
142- function startGame ( lobbyIdx ) {
143- var lob = lobbies [ lobbyIdx ] , conn1 = lob . players [ 0 ] [ 1 ] , conn2 = lob . players [ 1 ] [ 1 ] ; //lob is a reference
144- conn1 . removeListener ( connectionLobbyDataListener ) ;
145- conn2 . removeListener ( connectionLobbyDataListener ) ;
146- conn1 . write ( "game_start " + lob . players [ 1 ] [ 0 ] + "\n" ) ;
147- conn2 . write ( "game_start " + lob . players [ 0 ] [ 0 ] + "\n" ) ;
148- lob . game = { cube :fill_array ( function ( i ) { return 1 - Math . round ( Math . pow ( Math . random ( ) , 1.5 ) ) ; } ) , toMove :0 , player0at :0 , rot :0 } ;
149- //player0at=side facing player 0; rot=number of 90-degrees-multiples rotated from standard orientation
150-
183+ conn [ 0 ] . write ( "game_start " + lob . players [ 1 ] [ 0 ] + "\n" ) ;
184+ conn [ 1 ] . write ( "game_start " + lob . players [ 0 ] [ 0 ] + "\n" ) ;
185+ lob . game = {
186+ cube :fill_array ( 6 , function ( i ) {
187+ return fill_array ( 4 , function ( j ) {
188+ return 1 - Math . round ( Math . pow ( Math . random ( ) , 1.5 ) ) ;
189+ } ) ;
190+ } ) ,
191+ toMove :0 , player0at :1 , rot :0
192+ } ;
193+ //player0at=side that player 0 sees; rot=number of 90-degrees-multiples rotated from standard orientation
194+ conn [ 0 ] . write ( "your_cube_face " + getCubeFace ( lob . game . cube , lob . player0at , lob . rot ) + "\n" ) ;
195+ conn [ 1 ] . write ( "your_cube_face " + getCubeFace ( lob . game . cube , oppositeFace ( lob . player0at ) , lob . rot ) + "\n" ) ;
151196}
0 commit comments