UNPKG

8.03 kBJavaScriptView Raw
1const _ = require('lodash');
2const common = require('@screeps/common');
3const config = common.configManager.config;
4const C = config.common.constants;
5const db = common.storage.db;
6const env = common.storage.env;
7const q = require('q');
8const png = require('pngjs').PNG;
9const fs = require('fs');
10const path = require('path');
11
12exports.roomNameFromXY = function(x,y) {
13 if(x < 0) {
14 x = 'W'+(-x-1);
15 }
16 else {
17 x = 'E'+(x);
18 }
19 if(y < 0) {
20 y = 'N'+(-y-1);
21 }
22 else {
23 y = 'S'+(y);
24 }
25 return ""+x+y;
26}
27
28exports.roomNameToXY = function(name) {
29 var [match,hor,x,ver,y] = name.match(/^(\w)(\d+)(\w)(\d+)$/);
30 if(hor == 'W') {
31 x = -x-1;
32 }
33 else {
34 x = +x;
35 //x--;
36 }
37 if(ver == 'N') {
38 y = -y-1;
39 }
40 else {
41 y = +y;
42 //y--;
43 }
44 return [x,y];
45}
46
47exports.translateModulesFromDb = function(modules) {
48 modules = modules || {};
49
50 for(var key in modules) {
51 var newKey = key.replace(/\$DOT\$/g, '.');
52 newKey = newKey.replace(/\$SLASH\$/g, '/');
53 newKey = newKey.replace(/\$BACKSLASH\$/g, '\\');
54 if(newKey != key) {
55 modules[newKey] = modules[key];
56 delete modules[key];
57 }
58 }
59 return modules;
60};
61
62exports.translateModulesToDb = function(modules) {
63 modules = modules || {};
64
65 for(var key in modules) {
66 var newKey = key.replace(/\./g,'$DOT$');
67 newKey = newKey.replace(/\//g,'$SLASH$');
68 newKey = newKey.replace(/\\/g,'$BACKSLASH$');
69
70 if(newKey[0] == '$') {
71 delete modules[key];
72 continue;
73 }
74
75 if(newKey != key) {
76 modules[newKey] = modules[key];
77 delete modules[key];
78 }
79 }
80
81 if(!modules.main) {
82 modules.main = '';
83 }
84
85 return modules;
86};
87
88exports.getUserWorldStatus = function(user) {
89 return db['rooms.objects'].count({user: ""+user._id})
90 .then((objectsCnt) => {
91 if(!objectsCnt) {
92 return {status: 'empty'};
93 }
94 return db['rooms.objects'].find({$and: [
95 {user: ""+user._id},
96 {type: {$in: ['spawn','controller']}}
97 ]}).then((objects) => {
98 var spawns = false;
99 if(objects) {
100 objects.forEach((i) => {
101 if (i.type == 'spawn') {
102 if(!_.any(objects, {type: 'controller', room: i.room, user: i.user})) {
103 return;
104 }
105 spawns = true;
106 }
107 })
108 }
109 return {status: spawns ? 'normal' : 'lost'};
110 })
111 })
112};
113
114
115exports.respawnUser = function(userId) {
116
117 return db['rooms.objects'].find({$and: [{user: ""+userId}, {energy: {$gt: 0}}]})
118 .then((data) => {
119 if(!data.length) {
120 return q.when();
121 }
122 data = _.map(data, (i) => new Object({type: 'energy', room: i.room, x: i.x, y: i.y, energy: i.energy}));
123 return db['rooms.objects'].insert(data);
124 })
125 .then(() => db['rooms.objects'].removeWhere({$and: [
126 {user: ""+userId},
127 {type: {$ne: 'controller'}}]}))
128
129 .then(() => db['rooms.flags'].removeWhere({user: ""+userId}))
130
131 .then(() => db['rooms.objects'].find({$and: [{user: ""+userId}, {type: 'controller'}]}))
132
133 .then((controllers) => q.all(_.map(controllers, (i) => db.rooms.update({_id: i.room}, {$set: {status: 'normal'}}))))
134
135 .then(() => db['rooms.objects'].update({$and: [{user: "" + userId}, {type: 'controller'}]}, {
136 $set: {
137 level: 0,
138 hits: 0,
139 hitsMax: 0,
140 progress: 0,
141 progressTotal: 0,
142 user: null,
143 downgradeTime: null,
144 safeMode: null,
145 safeModeAvailable: 0,
146 safeModeCooldown: null
147 }
148 }));
149};
150
151exports.withHelp = function(array) {
152 var fn = array[1];
153 fn._help = array[0];
154 return fn;
155};
156
157exports.generateCliHelp = function(prefix, container) {
158 return `Available methods:\r\n`+Object.keys(container).filter(i => _.isFunction(container[i])).map(i => ' - ' + prefix + (container[i]._help || i)).join('\r\n');
159};
160
161exports.writePng = function(colors, width, height, filename) {
162
163 var image = new png({width, height});
164
165 for(var y=0; y<height; y++) {
166 for(var x=0; x<width; x++) {
167 var idx = (width*y + x) << 2;
168
169 image.data[idx] = colors[y][x][0];
170 image.data[idx+1] = colors[y][x][1];
171 image.data[idx+2] = colors[y][x][2];
172 image.data[idx+3] = colors[y][x][3] === undefined ? 255 : colors[y][x][3];
173 }
174 }
175
176 var defer = q.defer();
177 image.pack().pipe(fs.createWriteStream(filename)).on('finish', () => defer.resolve());
178 return defer.promise;
179};
180
181exports.createTerrainColorsMap = function(terrain, zoomIn) {
182 var colors = {},
183 width = 50, height = 50;
184
185 for(var y=0; y<height; y++) {
186 if(zoomIn) {
187 colors[y * 3] = {};
188 colors[y * 3 + 1] = {};
189 colors[y * 3 + 2] = {};
190 }
191 else {
192 colors[y] = {};
193 }
194 for(var x=0; x<width; x++) {
195
196 var color;
197 if(common.checkTerrain(terrain,x,y,C.TERRAIN_MASK_WALL)) {
198 color = [0,0,0];
199 }
200 else if(common.checkTerrain(terrain,x,y,C.TERRAIN_MASK_SWAMP)) {
201 color = [35,37,19];
202 }
203 else if(x == 0 || y == 0 || x == 49 || y == 49) {
204 color = [50,50,50];
205 }
206 else {
207 color = [43,43,43];
208 }
209 if(zoomIn) {
210 for (var dx = 0; dx < 3; dx++) {
211 for (var dy = 0; dy < 3; dy++) {
212 colors[y * 3 + dy][x * 3 + dx] = color;
213 }
214 }
215 }
216 else {
217 colors[y][x] = color;
218 }
219 }
220 }
221
222 return colors;
223};
224
225exports.writeTerrainToPng = function(terrain, filename, zoomIn) {
226
227 var colors = exports.createTerrainColorsMap(terrain, zoomIn);
228 return exports.writePng(colors, 50*(zoomIn?3:1), 50*(zoomIn?3:1), filename);
229};
230
231exports.loadBot = function(name) {
232 var dir = config.common.bots[name];
233 if(!dir) {
234 throw new Error(`Bot AI with the name "${name}" doesn't exist`);
235 }
236 var stat = fs.statSync(dir);
237 if (!stat.isDirectory()) {
238 throw new Error(`"${dir}" is not a directory`);
239 }
240 fs.statSync(path.resolve(dir, 'main.js'));
241 var files = fs.readdirSync(dir), modules = {};
242 files.forEach(file => {
243 var m = file.match(/^(.*)\.js$/);
244 if(!m) {
245 return;
246 }
247 modules[m[1]] = fs.readFileSync(path.resolve(dir, file), {encoding: 'utf8'});
248 });
249 return exports.translateModulesToDb(modules);
250};
251
252exports.reloadBotUsers = function(name) {
253
254 return db.users.find({bot: name})
255 .then(users => {
256 if(!users.length) {
257 return 'No bot players found';
258 }
259 var modules = exports.loadBot(name);
260 var timestamp = Date.now();
261
262 return db['users.code'].insert(users.map(i => ({
263 user: i._id,
264 branch: 't'+timestamp,
265 timestamp,
266 activeWorld: true,
267 activeSim: true,
268 modules
269 })))
270 .then(() => db['users.code'].removeWhere({$and: [
271 {user: {$in: users.map(i => i._id)}},
272 {branch: {$ne: 't'+timestamp}}
273 ]}))
274 .then(() => 'Reloaded scripts for users: '+users.map(i => i.username).join(', '));
275 })
276};
\No newline at end of file