@@ -5,12 +5,15 @@ const _ = require('lodash');
5
5
const getDbAdapterConfig = require ( "../lib/getDbAdapterConfig.js" ) ;
6
6
const fs = require ( 'fs' ) ;
7
7
const path = require ( 'path' ) ;
8
+ const selectOpponents = require ( './league/selectOpponents.js' ) ;
9
+ const updateScores = require ( './league/updateScores.js' ) ;
8
10
9
11
class LeagueService extends Service {
10
12
11
13
constructor ( broker ) {
12
14
super ( broker ) ;
13
-
15
+ this . config = broker . serviceConfig . league ;
16
+ this . queueLimit = broker . serviceConfig . ubdPlayer . queueLimit ;
14
17
let adapterConfig = getDbAdapterConfig ( broker . serviceConfig . data , 'league' )
15
18
this . parseServiceSchema ( {
16
19
...adapterConfig ,
@@ -25,7 +28,6 @@ class LeagueService extends Service {
25
28
"ownerName" ,
26
29
"scriptId" ,
27
30
"scriptName" ,
28
- "rank" ,
29
31
"fights_total" ,
30
32
"fights_win" ,
31
33
"fights_lose" ,
@@ -40,16 +42,19 @@ class LeagueService extends Service {
40
42
ownerName : { type : "string" , min : 1 , max : 255 } ,
41
43
scriptId : "string" ,
42
44
scriptName : { type : "string" , min : 1 , max : 255 } ,
43
- rank : "number" ,
44
45
fights_total : "number" ,
45
46
fights_win : "number" ,
46
47
fights_lose : "number" ,
47
48
fights_error : "number" ,
48
49
score : "number" ,
49
50
code : { type : "string" , min : 0 , max : 65536 } ,
50
51
} ,
51
- dependencies : [ 'scriptStore' ] ,
52
+ dependencies : [
53
+ 'scriptStore' ,
54
+ 'ubdPlayer'
55
+ ] ,
52
56
actions : {
57
+ scheduleBattle : this . scheduleBattle ,
53
58
seedLeague : this . seedLeague ,
54
59
getUserSubmission : this . getUserSubmission ,
55
60
joinLeague : this . joinLeague ,
@@ -61,12 +66,11 @@ class LeagueService extends Service {
61
66
create : [
62
67
function addDefaults ( ctx ) {
63
68
ctx . params . joinedAt = new Date ( ) ;
64
- ctx . params . rank = 0 ;
65
69
ctx . params . fights_total = 0 ;
66
70
ctx . params . fights_win = 0 ;
67
71
ctx . params . fights_lose = 0 ;
68
72
ctx . params . fights_error = 0 ;
69
- ctx . params . score = 0 ;
73
+ ctx . params . score = 1000 ;
70
74
ctx . params = _ . omit ( ctx . params , [ 'id' ] ) ;
71
75
return ctx ;
72
76
}
@@ -76,18 +80,85 @@ class LeagueService extends Service {
76
80
events : {
77
81
"app.seed" : async ( ctx ) => {
78
82
await ctx . call ( 'league.seedLeague' , { } )
83
+ } ,
84
+ "ubdPlayer.battle.league" : async ( ctx ) => {
85
+ if ( ctx . params . error ) {
86
+ this . logger . warn ( 'Battle failed between: ' + Object . keys ( ctx . params . refData ) . join ( ' and ' ) ) ;
87
+ return ;
88
+ }
89
+ await updateScores ( ctx , this . logger ) ;
79
90
}
91
+ } ,
92
+ started : ( ) => {
93
+ this . loop = setInterval ( async ( ) => {
94
+ try {
95
+ let queueLength = await broker . call ( 'ubdPlayer.getQueueLength' , { } ) ;
96
+ if ( queueLength >= this . queueLimit ) {
97
+ return ;
98
+ }
99
+ await broker . call ( 'league.scheduleBattle' , { } )
100
+ } catch ( err ) {
101
+ this . logger . warn ( err )
102
+ }
103
+ } , this . config . scheduleInterval )
104
+ } ,
105
+ stopped : ( ) => {
106
+ clearInterval ( this . loop )
80
107
}
81
108
} ) ;
82
109
}
83
110
111
+ async scheduleBattle ( ctx ) {
112
+ // pick random opponents
113
+ let opponents = await selectOpponents ( ctx ) ;
114
+
115
+ // build UBD
116
+ let ubd = {
117
+ version : 3 ,
118
+ rngSeed : Math . random ( ) ,
119
+ teamMode : true ,
120
+ timeLimit : this . config . timeLimit ,
121
+ aiList : [ ]
122
+ } ;
123
+
124
+ let i ;
125
+ for ( i = 0 ; i < this . config . teamSize ; i ++ ) {
126
+ for ( let opponent of opponents ) {
127
+ ubd . aiList . push ( {
128
+ name : opponent . ownerName === 'jsbattle' ? opponent . scriptName : opponent . ownerName ,
129
+ team : opponent . ownerName + '/' + opponent . scriptName ,
130
+ code : opponent . code ,
131
+ initData : null ,
132
+ useSandbox : true ,
133
+ executionLimit : 100
134
+ } ) ;
135
+ }
136
+ }
137
+
138
+ this . logger . debug ( `Scheduling battle ${ opponents [ 0 ] . scriptName } vs ${ opponents [ 1 ] . scriptName } ` )
139
+
140
+ try {
141
+ let refData = { } ;
142
+ refData [ opponents [ 0 ] . ownerName + '/' + opponents [ 0 ] . scriptName ] = opponents [ 0 ] . id ;
143
+ refData [ opponents [ 1 ] . ownerName + '/' + opponents [ 1 ] . scriptName ] = opponents [ 1 ] . id ;
144
+ await ctx . call ( 'ubdPlayer.scheduleBattle' , {
145
+ ubd : ubd ,
146
+ event : 'league' ,
147
+ refData : refData
148
+ } ) ;
149
+ } catch ( err ) {
150
+ this . logger . debug ( 'Unable to schedule battle due to: ' + err . message )
151
+ }
152
+
153
+ }
154
+
84
155
async seedLeague ( ctx ) {
85
156
const seedPath = path . resolve ( __dirname , 'league' , 'seed' ) ;
86
157
const seedFiles = fs . readdirSync ( seedPath )
87
- . map ( ( filename ) => ( {
88
- ownerId : 0 ,
158
+ . map ( ( filename , index ) => ( {
159
+ ownerId : 'int-user-0000-1' ,
89
160
ownerName : 'jsbattle' ,
90
- scriptId : 0 ,
161
+ scriptId : 'int-script-0000-' + ( index + 1 ) ,
91
162
scriptName : filename . replace ( / \. t a n k $ / , '' ) ,
92
163
code : fs . readFileSync ( path . resolve ( seedPath , filename ) , 'utf8' )
93
164
} ) )
@@ -178,10 +249,9 @@ class LeagueService extends Service {
178
249
}
179
250
180
251
let ranktable = await ctx . call ( 'league.find' , {
181
- sort : 'rank '
252
+ sort : '-score '
182
253
} ) ;
183
- ranktable = ranktable . map ( ( item ) => _ . pick ( item , [
184
- "rank" ,
254
+ const fields = [
185
255
"ownerId" ,
186
256
"ownerName" ,
187
257
"scriptId" ,
@@ -192,22 +262,11 @@ class LeagueService extends Service {
192
262
"fights_lose" ,
193
263
"fights_error" ,
194
264
"score"
195
- ] ) ) ;
265
+ ]
266
+ ranktable = ranktable . map ( ( item ) => _ . pick ( item , fields ) ) ;
196
267
197
268
let submission = await this . getUserSubmission ( ctx )
198
- submission = _ . pick ( submission , [
199
- "rank" ,
200
- "ownerId" ,
201
- "ownerName" ,
202
- "scriptId" ,
203
- "scriptName" ,
204
- "joinedAt" ,
205
- "fights_total" ,
206
- "fights_win" ,
207
- "fights_lose" ,
208
- "fights_error" ,
209
- "score"
210
- ] ) ;
269
+ submission = _ . pick ( submission , fields ) ;
211
270
212
271
return {
213
272
submission,
0 commit comments