UNPKG

8.55 kBJavaScriptView Raw
1const common = require('@screeps/common');
2const C = common.configManager.config.common.constants;
3const bots = common.configManager.config.common.bots;
4const db = common.storage.db;
5const env = common.storage.env;
6const utils = require('../utils');
7const q = require('q');
8const fs = require('fs');
9const path = require('path');
10const _ = require('lodash');
11
12var boyNames = [ 'Jackson', 'Aiden', 'Liam', 'Lucas', 'Noah', 'Mason', 'Jayden', 'Ethan', 'Jacob', 'Jack', 'Caden', 'Logan', 'Benjamin', 'Michael', 'Caleb', 'Ryan', 'Alexander', 'Elijah', 'James', 'William', 'Oliver', 'Connor', 'Matthew', 'Daniel', 'Luke', 'Brayden', 'Jayce', 'Henry', 'Carter', 'Dylan', 'Gabriel', 'Joshua', 'Nicholas', 'Isaac', 'Owen', 'Nathan', 'Grayson', 'Eli', 'Landon', 'Andrew', 'Max', 'Samuel', 'Gavin', 'Wyatt', 'Christian', 'Hunter', 'Cameron', 'Evan', 'Charlie', 'David', 'Sebastian', 'Joseph', 'Dominic', 'Anthony', 'Colton', 'John', 'Tyler', 'Zachary', 'Thomas', 'Julian', 'Levi', 'Adam', 'Isaiah', 'Alex', 'Aaron', 'Parker', 'Cooper', 'Miles', 'Chase', 'Muhammad', 'Christopher', 'Blake', 'Austin', 'Jordan', 'Leo', 'Jonathan', 'Adrian', 'Colin', 'Hudson', 'Ian', 'Xavier', 'Camden', 'Tristan', 'Carson', 'Jason', 'Nolan', 'Riley', 'Lincoln', 'Brody', 'Bentley', 'Nathaniel', 'Josiah', 'Declan', 'Jake', 'Asher', 'Jeremiah', 'Cole', 'Mateo', 'Micah', 'Elliot' ],
13 girlNames = [ 'Sophia', 'Emma', 'Olivia', 'Isabella', 'Mia', 'Ava', 'Lily', 'Zoe', 'Emily', 'Chloe', 'Layla', 'Madison', 'Madelyn', 'Abigail', 'Aubrey', 'Charlotte', 'Amelia', 'Ella', 'Kaylee', 'Avery', 'Aaliyah', 'Hailey', 'Hannah', 'Addison', 'Riley', 'Harper', 'Aria', 'Arianna', 'Mackenzie', 'Lila', 'Evelyn', 'Adalyn', 'Grace', 'Brooklyn', 'Ellie', 'Anna', 'Kaitlyn', 'Isabelle', 'Sophie', 'Scarlett', 'Natalie', 'Leah', 'Sarah', 'Nora', 'Mila', 'Elizabeth', 'Lillian', 'Kylie', 'Audrey', 'Lucy', 'Maya', 'Annabelle', 'Makayla', 'Gabriella', 'Elena', 'Victoria', 'Claire', 'Savannah', 'Peyton', 'Maria', 'Alaina', 'Kennedy', 'Stella', 'Liliana', 'Allison', 'Samantha', 'Keira', 'Alyssa', 'Reagan', 'Molly', 'Alexandra', 'Violet', 'Charlie', 'Julia', 'Sadie', 'Ruby', 'Eva', 'Alice', 'Eliana', 'Taylor', 'Callie', 'Penelope', 'Camilla', 'Bailey', 'Kaelyn', 'Alexis', 'Kayla', 'Katherine', 'Sydney', 'Lauren', 'Jasmine', 'London', 'Bella', 'Adeline', 'Caroline', 'Vivian', 'Juliana', 'Gianna', 'Skyler', 'Jordyn' ];
14
15function genRandomUserName(c) {
16 c = c || 0;
17
18 var name;
19
20
21 var list = Math.random() > 0.5 ? boyNames : girlNames;
22 name = list[Math.floor(Math.random()*list.length)];
23
24 if(c > 3) {
25 name += list[Math.floor(Math.random()*list.length)];
26 }
27
28 return db.users.findOne({username: name+'Bot'})
29 .then(result => {
30 if(result) {
31 return genRandomUserName(c+1);
32 }
33 return name+'Bot';
34 });
35}
36
37function genRandomBadge() {
38 var badge = {};
39 badge.type = Math.floor(Math.random()*24)+1;
40 badge.color1 = '#'+Math.floor(Math.random()*0xffffff).toString(16);
41 badge.color2 = '#'+Math.floor(Math.random()*0xffffff).toString(16);
42 badge.color3 = '#'+Math.floor(Math.random()*0xffffff).toString(16);
43 badge.flip = Math.random() > 0.5;
44 badge.param = Math.floor(Math.random()*200) - 100;
45 return badge;
46}
47
48exports.spawn = utils.withHelp([
49 `spawn(botAiName, roomName, [opts]) - Create a new NPC player with bot AI scripts, and spawn it to the specified room. 'opts' is an object with the following optional properties:\r
50 * name - the name of a bot player, default is randomly generated\r
51 * cpu - the CPU limit of a bot user, default is 100\r
52 * gcl - the Global Control Level of a bot user, default is 1\r
53 * x - the X position of the spawn in the room, default is random\r
54 * y - the Y position of the spawn in the room, default is random`,
55 function spawn(botAiName, roomName, opts) {
56 opts = opts || {};
57 try {
58 var modules = utils.loadBot(botAiName), user;
59 return db['rooms.objects'].findOne({$and: [{room: roomName}, {type: 'controller'}]})
60 .then(controller => {
61 if(!controller) {
62 return q.reject(`Room controller not found in ${roomName}`);
63 }
64 if(controller.user) {
65 return q.reject(`Room ${roomName} is already owned`);
66 }
67 })
68 .then(() => !opts.username ? genRandomUserName() :
69 db.users.findOne({username: opts.username}).then(user => user ? q.reject(`User with the name "${opts.username}" already exists`) : opts.username))
70 .then(username => {
71 var _user = {
72 username,
73 usernameLower: username.toLowerCase(),
74 cpu: opts.cpu || 100,
75 gcl: opts.gcl ? C.GCL_MULTIPLY * Math.pow(opts.gcl - 1, C.GCL_POW) : 0,
76 cpuAvailable: 0,
77 registeredDate: new Date(),
78 bot: botAiName,
79 active: 10000,
80 badge: genRandomBadge()
81 };
82 return db.users.insert(_user);
83 })
84 .then(_user => {
85 user = _user;
86 return db['users.code'].insert({
87 user: user._id,
88 modules,
89 branch: 'default',
90 activeWorld: true,
91 activeSim: true
92 });
93 })
94 .then(() => env.set(env.keys.MEMORY+user._id, "{}"))
95 .then(() => db['rooms.terrain'].findOne({room: roomName}))
96 .then(terrainItem => {
97 var x = opts.x || Math.floor(3 + Math.random()*46);
98 var y = opts.y || Math.floor(3 + Math.random()*46);
99 while(common.checkTerrain(terrainItem.terrain, x, y, C.TERRAIN_MASK_WALL)) {
100 x = Math.floor(3 + Math.random()*46);
101 y = Math.floor(3 + Math.random()*46);
102 }
103 return db['rooms.objects'].insert({
104 type: 'spawn',
105 room: roomName,
106 x,
107 y,
108 name: 'Spawn1',
109 user: user._id,
110 energy: C.SPAWN_ENERGY_START,
111 energyCapacity: C.SPAWN_ENERGY_CAPACITY,
112 hits: C.SPAWN_HITS,
113 hitsMax: C.SPAWN_HITS,
114 spawning: null,
115 notifyWhenAttacked: false
116 });
117 })
118 .then(common.getGametime)
119 .then(gameTime => db['rooms.objects'].update({$and: [{room: roomName}, {type: 'controller'}]}, {$set: {
120 user: user._id, level: 1, progress: 0, downgradeTime: null, safeMode: gameTime + 20000
121 }}))
122 .then(() => db.rooms.update({_id: roomName}, {$set: {active: true, invaderGoal: 1000000}}))
123 .then(() => `User ${user.username} with bot AI "${botAiName}" spawned in ${roomName}`);
124 }
125 catch(e) {
126 return q.reject(e);
127 }
128 }
129]);
130
131exports.reload = utils.withHelp([
132 "reload(botAiName) - Reload scripts for the specified bot AI.",
133 function reload(botAiName) {
134 return utils.reloadBotUsers(botAiName);
135 }
136]);
137
138exports.removeUser = utils.withHelp([
139 "removeUser(username) - Delete the specified bot player and all its game objects.",
140 function removeUser(username) {
141 return db.users.findOne({username})
142 .then(user => {
143 if(!user) {
144 return q.reject('User not found');
145 }
146 if(!user.bot) {
147 return q.reject('User is not a bot');
148 }
149 return utils.respawnUser(user._id)
150 .then(db.users.removeWhere({_id: user._id}))
151 .then(db['users.code'].removeWhere({user: user._id}))
152 .then(env.del(env.keys.MEMORY+user._id))
153 .then(() => `User removed successfully`);
154 })
155 }
156]);
157
158exports._help = utils.generateCliHelp('bots.', exports)+`\r\nBot AIs:\r\n`+
159 Object.keys(bots).map(botName => ` - ${botName} [${bots[botName]}]`).join(`\r\n`);