Passed
Push — master ( dce7e6...e2e6ab )
by Vincent
06:59 queued 12s
created

preload(String)   A

Complexity

Conditions 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
/*
2
 * This file is part of Araknemu.
3
 *
4
 * Araknemu is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Araknemu is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with Araknemu.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2017-2020 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.game;
21
22
import fr.quatrevieux.araknemu.core.config.ConfigurationModule;
23
import fr.quatrevieux.araknemu.core.config.Pool;
24
import fr.quatrevieux.araknemu.core.config.PoolUtils;
25
import org.apache.commons.lang3.StringUtils;
26
import org.checkerframework.checker.index.qual.NonNegative;
27
import org.checkerframework.checker.index.qual.Positive;
28
import org.checkerframework.common.value.qual.IntRange;
29
30
import java.time.Duration;
31
import java.util.Arrays;
32
33
/**
34
 * Configuration class for game server
35
 */
36
public final class GameConfiguration {
37 1
    public static final ConfigurationModule<GameConfiguration> MODULE = new ConfigurationModule<GameConfiguration>() {
38
        @Override
39
        public GameConfiguration create(Pool pool) {
40 1
            return new GameConfiguration(pool);
41
        }
42
43
        @Override
44
        public String name() {
45 1
            return "game";
46
        }
47
    };
48
49
    private final PoolUtils pool;
50
51 1
    public GameConfiguration(Pool pool) {
52 1
        this.pool = new PoolUtils(pool);
53 1
    }
54
55
    /**
56
     * Get the server ID. By default 1
57
     */
58
    public int id() {
59 1
        return pool.integer("id", 1);
60
    }
61
62
    /**
63
     * Get the server port
64
     */
65
    public int port() {
66 1
        return pool.integer("server.port", 5555);
67
    }
68
69
    /**
70
     * Get the server IP address
71
     */
72
    public String ip() {
73 1
        return pool.string("server.ip", "127.0.0.1");
74
    }
75
76
    /**
77
     * The maximum inactivity time, as duration
78
     * By default, 15min ("PT15M" or "15m")
79
     */
80
    public Duration inactivityTime() {
81 1
        return pool.duration("inactivityTime", Duration.ofMinutes(15));
82
    }
83
84
    /**
85
     * Maximum number of received packets per seconds per clients
86
     * When the limit is reached, the client session is closed
87
     */
88
    public int packetRateLimit() {
89 1
        return pool.integer("packetRateLimit", 100);
90
    }
91
92
    /**
93
     * Get the shutdown reminder delays, in minutes
94
     * The values are integer separated by a comma ","
95
     * Default value : "1,10,30,60,120"
96
     */
97
    public long[] shutdownReminderMinutes() {
98 1
        return Arrays.stream(StringUtils.split(pool.string("shutdownReminderMinutes", "1,10,30,60,120"), ","))
99 1
            .map(String::trim)
100 1
            .mapToLong(Long::parseLong)
101 1
            .sorted()
102 1
            .toArray()
103
        ;
104
    }
105
106
    /**
107
     * Get the refresh interval for the ban ip table
108
     * Default: 10 minutes (10m)
109
     */
110
    public Duration banIpRefresh() {
111 1
        return pool.duration("banip.refresh", Duration.ofMinutes(10));
112
    }
113
114
    /**
115
     * The interval between two automatic save of connected players
116
     * Note: Players are regularly saved apart of autosave, so it's not required to set a small value
117
     * Default: 4 hours (4h)
118
     */
119
    public Duration autosaveInterval() {
120 1
        return pool.duration("autosave.interval", Duration.ofHours(4));
121
    }
122
123
    /**
124
     * Enable automatic saving of connected players
125
     * Default: true
126
     */
127
    public boolean autosaveEnabled() {
128 1
        return pool.bool("autosave.enabled", true);
129
    }
130
131
    /**
132
     * Does preload is enabled for the given service
133
     * By default this value is true
134
     *
135
     * In case of submodule (i.e. preload.service.submodule), the preload will be checked on each part.
136
     * So if "preload.service" is false, "preload.service.submodule" will be considered as false
137
     *
138
     * @param service The service name
139
     *
140
     * @return true if preload is enabled
141
     *
142
     * @see PreloadableService#name() For the name of the server
143
     */
144
    public boolean preload(String service) {
145 1
        final String key = "preload." + service;
146
147 1
        for (int pos = key.indexOf('.'); pos != -1; pos = key.indexOf('.', pos + 1)) {
148 1
            if (!pool.bool(key.substring(0, pos), true)) {
149 1
                return false;
150
            }
151
        }
152
153 1
        return pool.bool(key, true);
154
    }
155
156
    /**
157
     * Get player configuration
158
     */
159
    public PlayerConfiguration player() {
160 1
        return new PlayerConfiguration();
161
    }
162
163
    /**
164
     * Get the chat configuration
165
     */
166
    public ChatConfiguration chat() {
167 1
        return new ChatConfiguration();
168
    }
169
170
    /**
171
     * Get the configuration for the game activity
172
     */
173
    public ActivityConfiguration activity() {
174 1
        return new ActivityConfiguration();
175
    }
176
177
    /**
178
     * Get the configuration for the Dofus economy
179
     */
180
    public EconomyConfiguration economy() {
181 1
        return new EconomyConfiguration();
182
    }
183
184
    /**
185
     * Get the configuration for the fight system
186
     */
187
    public FightConfiguration fight() {
188 1
        return new FightConfiguration();
189
    }
190
191 1
    public final class PlayerConfiguration {
192
        /**
193
         * The player name regex
194
         */
195
        public String nameRegex() {
196 1
            return pool.string("player.name.regex", "[A-Z][a-z]+(-[A-Z]?[a-z]+)?");
197
        }
198
199
        /**
200
         * Minimal length of player name
201
         */
202
        public @Positive int nameMinLength() {
203 1
            return pool.positiveInteger("player.name.minLength", 2);
204
        }
205
206
        /**
207
         * Maximal length of player name
208
         */
209
        public @Positive int nameMaxLength() {
210 1
            return pool.positiveInteger("player.name.maxLength", 20);
211
        }
212
213
        /**
214
         * Maximal length for generated name
215
         */
216
        public @Positive int maxNameGeneratedLength() {
217 1
            return pool.positiveInteger("player.name.generated.maxLength", 8);
218
        }
219
220
        /**
221
         * Minimal length for generated name
222
         */
223
        public @Positive int minNameGeneratedLength() {
224 1
            return pool.positiveInteger("player.name.generated.minLength", 4);
225
        }
226
227
        /**
228
         * Maximum number for characters per account per server
229
         */
230
        public int maxPerAccount() {
231 1
            return pool.integer("player.max", 5);
232
        }
233
234
        /**
235
         * Minimum level which needs secret answer for delete the character
236
         * By default, value is set to 20
237
         *
238
         * To change this value, you should also change in lang.swf, the value `C.SECRET_ANSWER_SINCE_LEVEL`
239
         */
240
        public @Positive int deleteAnswerLevel() {
241 1
            return pool.positiveInteger("player.deleteAnswerLevel", 20);
242
        }
243
244
        /**
245
         * Get the level up spell points
246
         * By default, value is set to 1
247
         */
248
        public @NonNegative int spellBoostPointsOnLevelUp() {
249 1
            return pool.nonNegativeInteger("player.level.spellPoints", 1);
250
        }
251
252
        /**
253
         * Get the level up characteristic points
254
         * By default, value is set to 5
255
         */
256
        public @NonNegative int characteristicPointsOnLevelUp() {
257 1
            return pool.nonNegativeInteger("player.level.characteristicPoints", 5);
258
        }
259
260
        /**
261
         * The life regeneration rate.
262
         * This is the number of milliseconds required to regenerate 1 life point. Set to 0 to disable.
263
         * By default 1000 (1 LP / sec)
264
         */
265
        public @NonNegative int baseLifeRegeneration() {
266 1
            return pool.nonNegativeInteger("player.lifeRegeneration.base", 1000);
267
        }
268
269
        /**
270
         * Restore life points when player reach a new level
271
         * By default true
272
         */
273
        public boolean restoreLifeOnLevelUp() {
274 1
            return pool.bool("player.restoreLifeOnLevelUp", true);
275
        }
276
    }
277
278 1
    public final class ChatConfiguration {
279
        /**
280
         * Get the waiting time in seconds for global channel flood
281
         *
282
         * Set to -1 for deactivate
283
         */
284
        public int floodTime() {
285 1
            return pool.integer("chat.flood.time", 30);
286
        }
287
288
        /**
289
         * Get list of default channels to add on character creation
290
         */
291
        public String defaultChannels() {
292 1
            return pool.string("chat.channels.default", "*#%!pi$:?");
293
        }
294
295
        /**
296
         * Channels to add on admin characters
297
         */
298
        public String adminChannels() {
299 1
            return pool.string("chat.channels.admin", "@");
300
        }
301
    }
302
303 1
    public final class ActivityConfiguration {
304
        /**
305
         * Number of threads to use for the activity service
306
         */
307
        public @Positive int threadsCount() {
308 1
            return pool.positiveInteger("activity.threadsCount", 1);
309
        }
310
311
        /**
312
         * Number of seconds for move monster groups
313
         * By default 120s = 2min
314
         */
315
        public int monsterMoveInterval() {
316 1
            return pool.integer("activity.monsters.moveInterval", 120);
317
        }
318
319
        /**
320
         * Percent of chance that a monster group on a map move
321
         * The value must be an integer value between ]0, 100]
322
         * By default 25%
323
         */
324
        public @IntRange(from = 0, to = 100) int monsterMovePercent() {
325 1
            return pool.percent("activity.monsters.movePercent", 25);
326
        }
327
328
        /**
329
         * The maximum move distance for monsters
330
         * By default 5
331
         */
332
        public @Positive int monsterMoveDistance() {
333 1
            return pool.positiveInteger("activity.monsters.moveDistance", 5);
334
        }
335
336
        /**
337
         * The delay divisor for respawn a monster group
338
         * With a factor of 2, the respawn will be 2 times faster
339
         * By default 1
340
         */
341
        public @Positive int monsterRespawnSpeedFactor() {
342 1
            return pool.positiveInteger("activity.monsters.respawnSpeedFactor", 1);
343
        }
344
    }
345
346 1
    public final class EconomyConfiguration {
347
        /**
348
         * Get the selling item to an NPC price multiplier
349
         * By default 0.1
350
         *
351
         * Should corresponds to "C.SELL_PRICE_MULTIPLICATOR" in lang_xx_xxx.swf
352
         */
353
        public double npcSellPriceMultiplier() {
354 1
            return pool.decimal("economy.npc.sellPriceMultiplier", .1d);
355
        }
356
357
        /**
358
         * The bank cost per item entries
359
         * The value must be a positive double
360
         * Default to 1
361
         * Set to 0 to disable the bank cost
362
         */
363
        public double bankCostPerEntry() {
364 1
            return pool.decimal("economy.bank.costPerEntry", 1);
365
        }
366
    }
367
368 1
    public final class FightConfiguration {
369
        /**
370
         * The threads count for run fight actions and AI
371
         * This value should be greater than 2. A good value may be around 1 thread per 100 fights
372
         * By default, 4
373
         */
374
        public int threadsCount() {
375 1
            return pool.integer("fight.threadsCount", 4);
376
        }
377
378
        /**
379
         * The fight turn duration
380
         * The value should be a duration string like 30s, 1m10s
381
         * Default value : 30s
382
         */
383
        public Duration turnDuration() {
384 1
            return pool.duration("fight.turnDuration", Duration.ofSeconds(30));
385
        }
386
387
        /**
388
         * The placement duration for a PVM fight
389
         * The value should be a duration string like 30s, 1m10s
390
         * Default value : 45s
391
         */
392
        public Duration pvmPlacementDuration() {
393 1
            return pool.duration("fight.pvm.placementDuration", Duration.ofSeconds(45));
394
        }
395
396
        /**
397
         * Get the XP multiplier
398
         * The value should be a positive decimal number.
399
         * Default value : 1.0
400
         */
401
        public double xpRate() {
402 1
            return pool.decimal("fight.rate.xp", 1.0);
403
        }
404
405
        /**
406
         * Get the drop rate multiplier
407
         * The value should be a positive decimal number.
408
         * This value will modify the object drop chance, but not the maximum dropped items per monster
409
         * nor minimal discernment requirement.
410
         * Default value : 1.0
411
         */
412
        public double dropRate() {
413 1
            return pool.decimal("fight.rate.drop", 1.0);
414
        }
415
    }
416
}
417