Passed
Push — master ( 98b9ef...f07afa )
by Vincent
06:37 queued 12s
created

xpRate()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
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
     * Get player configuration
133
     */
134
    public PlayerConfiguration player() {
135 1
        return new PlayerConfiguration();
136
    }
137
138
    /**
139
     * Get the chat configuration
140
     */
141
    public ChatConfiguration chat() {
142 1
        return new ChatConfiguration();
143
    }
144
145
    /**
146
     * Get the configuration for the game activity
147
     */
148
    public ActivityConfiguration activity() {
149 1
        return new ActivityConfiguration();
150
    }
151
152
    /**
153
     * Get the configuration for the Dofus economy
154
     */
155
    public EconomyConfiguration economy() {
156 1
        return new EconomyConfiguration();
157
    }
158
159
    /**
160
     * Get the configuration for the fight system
161
     */
162
    public FightConfiguration fight() {
163 1
        return new FightConfiguration();
164
    }
165
166 1
    public final class PlayerConfiguration {
167
        /**
168
         * The player name regex
169
         */
170
        public String nameRegex() {
171 1
            return pool.string("player.name.regex", "[A-Z][a-z]+(-[A-Z]?[a-z]+)?");
172
        }
173
174
        /**
175
         * Minimal length of player name
176
         */
177
        public @Positive int nameMinLength() {
178 1
            return pool.positiveInteger("player.name.minLength", 2);
179
        }
180
181
        /**
182
         * Maximal length of player name
183
         */
184
        public @Positive int nameMaxLength() {
185 1
            return pool.positiveInteger("player.name.maxLength", 20);
186
        }
187
188
        /**
189
         * Maximal length for generated name
190
         */
191
        public @Positive int maxNameGeneratedLength() {
192 1
            return pool.positiveInteger("player.name.generated.maxLength", 8);
193
        }
194
195
        /**
196
         * Minimal length for generated name
197
         */
198
        public @Positive int minNameGeneratedLength() {
199 1
            return pool.positiveInteger("player.name.generated.minLength", 4);
200
        }
201
202
        /**
203
         * Maximum number for characters per account per server
204
         */
205
        public int maxPerAccount() {
206 1
            return pool.integer("player.max", 5);
207
        }
208
209
        /**
210
         * Minimum level which needs secret answer for delete the character
211
         * By default, value is set to 20
212
         *
213
         * To change this value, you should also change in lang.swf, the value `C.SECRET_ANSWER_SINCE_LEVEL`
214
         */
215
        public @Positive int deleteAnswerLevel() {
216 1
            return pool.positiveInteger("player.deleteAnswerLevel", 20);
217
        }
218
219
        /**
220
         * Get the level up spell points
221
         * By default, value is set to 1
222
         */
223
        public @NonNegative int spellBoostPointsOnLevelUp() {
224 1
            return pool.nonNegativeInteger("player.level.spellPoints", 1);
225
        }
226
227
        /**
228
         * Get the level up characteristic points
229
         * By default, value is set to 5
230
         */
231
        public @NonNegative int characteristicPointsOnLevelUp() {
232 1
            return pool.nonNegativeInteger("player.level.characteristicPoints", 5);
233
        }
234
235
        /**
236
         * The life regeneration rate.
237
         * This is the number of milliseconds required to regenerate 1 life point. Set to 0 to disable.
238
         * By default 1000 (1 LP / sec)
239
         */
240
        public @NonNegative int baseLifeRegeneration() {
241 1
            return pool.nonNegativeInteger("player.lifeRegeneration.base", 1000);
242
        }
243
244
        /**
245
         * Restore life points when player reach a new level
246
         * By default true
247
         */
248
        public boolean restoreLifeOnLevelUp() {
249 1
            return pool.bool("player.restoreLifeOnLevelUp", true);
250
        }
251
    }
252
253 1
    public final class ChatConfiguration {
254
        /**
255
         * Get the waiting time in seconds for global channel flood
256
         *
257
         * Set to -1 for deactivate
258
         */
259
        public int floodTime() {
260 1
            return pool.integer("chat.flood.time", 30);
261
        }
262
263
        /**
264
         * Get list of default channels to add on character creation
265
         */
266
        public String defaultChannels() {
267 1
            return pool.string("chat.channels.default", "*#%!pi$:?");
268
        }
269
270
        /**
271
         * Channels to add on admin characters
272
         */
273
        public String adminChannels() {
274 1
            return pool.string("chat.channels.admin", "@");
275
        }
276
    }
277
278 1
    public final class ActivityConfiguration {
279
        /**
280
         * Number of threads to use for the activity service
281
         */
282
        public @Positive int threadsCount() {
283 1
            return pool.positiveInteger("activity.threadsCount", 1);
284
        }
285
286
        /**
287
         * Number of seconds for move monster groups
288
         * By default 120s = 2min
289
         */
290
        public int monsterMoveInterval() {
291 1
            return pool.integer("activity.monsters.moveInterval", 120);
292
        }
293
294
        /**
295
         * Percent of chance that a monster group on a map move
296
         * The value must be an integer value between ]0, 100]
297
         * By default 25%
298
         */
299
        public @IntRange(from = 0, to = 100) int monsterMovePercent() {
300 1
            return pool.percent("activity.monsters.movePercent", 25);
301
        }
302
303
        /**
304
         * The maximum move distance for monsters
305
         * By default 5
306
         */
307
        public @Positive int monsterMoveDistance() {
308 1
            return pool.positiveInteger("activity.monsters.moveDistance", 5);
309
        }
310
311
        /**
312
         * The delay divisor for respawn a monster group
313
         * With a factor of 2, the respawn will be 2 times faster
314
         * By default 1
315
         */
316
        public @Positive int monsterRespawnSpeedFactor() {
317 1
            return pool.positiveInteger("activity.monsters.respawnSpeedFactor", 1);
318
        }
319
    }
320
321 1
    public final class EconomyConfiguration {
322
        /**
323
         * Get the selling item to an NPC price multiplier
324
         * By default 0.1
325
         *
326
         * Should corresponds to "C.SELL_PRICE_MULTIPLICATOR" in lang_xx_xxx.swf
327
         */
328
        public double npcSellPriceMultiplier() {
329 1
            return pool.decimal("economy.npc.sellPriceMultiplier", .1d);
330
        }
331
332
        /**
333
         * The bank cost per item entries
334
         * The value must be a positive double
335
         * Default to 1
336
         * Set to 0 to disable the bank cost
337
         */
338
        public double bankCostPerEntry() {
339 1
            return pool.decimal("economy.bank.costPerEntry", 1);
340
        }
341
    }
342
343 1
    public final class FightConfiguration {
344
        /**
345
         * The threads count for run fight actions and AI
346
         * This value should be greater than 2. A good value may be around 1 thread per 100 fights
347
         * By default, 4
348
         */
349
        public int threadsCount() {
350 1
            return pool.integer("fight.threadsCount", 4);
351
        }
352
353
        /**
354
         * The fight turn duration
355
         * The value should be a duration string like 30s, 1m10s
356
         * Default value : 30s
357
         */
358
        public Duration turnDuration() {
359 1
            return pool.duration("fight.turnDuration", Duration.ofSeconds(30));
360
        }
361
362
        /**
363
         * The placement duration for a PVM fight
364
         * The value should be a duration string like 30s, 1m10s
365
         * Default value : 45s
366
         */
367
        public Duration pvmPlacementDuration() {
368 1
            return pool.duration("fight.pvm.placementDuration", Duration.ofSeconds(45));
369
        }
370
371
        /**
372
         * Get the XP multiplier
373
         * The value should be a positive decimal number.
374
         * Default value : 1.0
375
         */
376
        public double xpRate() {
377 1
            return pool.decimal("fight.rate.xp", 1.0);
378
        }
379
380
        /**
381
         * Get the drop rate multiplier
382
         * The value should be a positive decimal number.
383
         * This value will modify the object drop chance, but not the maximum dropped items per monster
384
         * nor minimal discernment requirement.
385
         * Default value : 1.0
386
         */
387
        public double dropRate() {
388 1
            return pool.decimal("fight.rate.drop", 1.0);
389
        }
390
    }
391
}
392