forked from RanvierMUD/ranviermud
-
Notifications
You must be signed in to change notification settings - Fork 0
/
whispermud
executable file
·157 lines (134 loc) · 5.18 KB
/
whispermud
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env node
'use strict';
/**
* Main file, use this to run the server:
* node whispermud [options]
*
* Options:
* -v Verbose loggin
* --port Port to listen on
*/
/* NPM Modules */
const semver = require('semver');
const net = require('net');
const commander = require('commander');
const argv = require('optimist').argv;
const fs = require('fs');
// for dev clone the github:whispermudmud/core repo, and run npm link in that folder, then come
// back to the whispermudmud repo and run npm link whispermud
const Core = require('whispermud-core');
const Config = Core.Config;
// Package.json for versioning
const pkg = require('./package.json');
if (!semver.satisfies(process.version, pkg.engines.node)) {
throw new Error(
`WhisperMud's core engine requires Node version ${pkg.engines.node},
you are currently running Node ${process.version}.`
);
}
// Wrapper for whispermud.json
Core.Data.setDataPath(__dirname + '/data/');
if (fs.existsSync('./whispermud.conf.js')) {
Config.load(require('./whispermud.conf.js'));
} else if (fs.existsSync('./whispermud.json')) {
Config.load(require('./whispermud.json'));
} else {
console.error('ERROR: No whispermud.json or whispermud.conf.js found');
process.exit(1);
}
// cmdline options
commander
.version(pkg.version)
.option('-p, --port [portNumber]', 'Port to host the server [23]', Core.Config.get('port', 23))
.option('-v, --verbose', 'Verbose console logging.', true)
.option('-e, --prettyErrors', 'Pretty-print formatting for error stack traces.', false)
.parse(process.argv);
// Set debug variable and encoding.
// 'net' by default to help find possible server errors.
process.env.NODE_DEBUG = 'net';
process.stdin.setEncoding('utf8');
const Logger = Core.Logger;
const logfile = Core.Config.get('logfile');
if (logfile) {
Logger.setFileLogging(`${__dirname}/log/${logfile}`);
}
if (commander.prettyErrors) {
Logger.enablePrettyErrors();
}
// Set logging level based on CLI option or environment variable.
const logLevel = commander.verbose ?
'verbose' :
process.env.LOG_LEVEL || Config.get('logLevel') || 'debug';
Logger.setLevel(logLevel);
// Global state object, server instance and configurable intervals.
let GameState = {};
let saveInterval, tickInterval, playerTickInterval;
/**
* Do the dirty work
*/
async function init(restartServer) {
Logger.log("START - Loading entities");
restartServer = typeof restartServer === 'undefined' ? true : restartServer;
GameState = {
AccountManager: new Core.AccountManager(),
AreaBehaviorManager: new Core.BehaviorManager(),
AreaFactory: new Core.AreaFactory(),
AreaManager: new Core.AreaManager(),
AttributeFactory: new Core.AttributeFactory(),
ChannelManager: new Core.ChannelManager(),
CommandManager: new Core.CommandManager(),
Config, // All global server settings like default respawn time, save interval, port, what bundles to load, etc.
EffectFactory: new Core.EffectFactory(),
HelpManager: new Core.HelpManager(),
InputEventManager: new Core.EventManager(),
ItemBehaviorManager: new Core.BehaviorManager(),
ItemFactory: new Core.ItemFactory(),
ItemManager: new Core.ItemManager(),
MobBehaviorManager: new Core.BehaviorManager(),
MobFactory: new Core.MobFactory(),
MobManager: new Core.MobManager(),
PartyManager: new Core.PartyManager(),
PlayerManager: new Core.PlayerManager(),
QuestFactory: new Core.QuestFactory(),
QuestGoalManager: new Core.QuestGoalManager(),
QuestRewardManager: new Core.QuestRewardManager(),
RoomBehaviorManager: new Core.BehaviorManager(),
RoomFactory: new Core.RoomFactory(),
RoomManager: new Core.RoomManager(),
SkillManager: new Core.SkillManager(),
SpellManager: new Core.SkillManager(),
ServerEventManager: new Core.EventManager(),
GameServer: new Core.GameServer(),
DataLoader: Core.Data,
EntityLoaderRegistry: new Core.EntityLoaderRegistry(),
DataSourceRegistry: new Core.DataSourceRegistry(),
Config,
};
// setup entity loaders
GameState.DataSourceRegistry.load(require, __dirname, Config.get('dataSources'));
GameState.EntityLoaderRegistry.load(GameState.DataSourceRegistry, Config.get('entityLoaders'));
GameState.AccountManager.setLoader(GameState.EntityLoaderRegistry.get('accounts'));
GameState.PlayerManager.setLoader(GameState.EntityLoaderRegistry.get('players'));
// Setup bundlemanager
const BundleManager = new Core.BundleManager(__dirname + '/bundles/', GameState);
GameState.BundleManager = BundleManager;
await BundleManager.loadBundles();
GameState.ServerEventManager.attach(GameState.GameServer);
if (restartServer) {
Logger.log("START - Starting server");
GameState.GameServer.startup(commander);
// Ticks for effect processing and combat happen every 100ms
clearInterval(tickInterval);
tickInterval = setInterval(() => {
GameState.AreaManager.tickAll(GameState);
GameState.ItemManager.tickAll();
}, Config.get('entityTickFrequency', 100));
clearInterval(playerTickInterval);
playerTickInterval = setInterval(() => {
GameState.PlayerManager.tickAll();
}, Config.get('playerTickFrequency', 100));
}
}
// START IT UP!
init();
// vim: set syn=javascript :