h1z1-server 0.45.0 → 0.45.2-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.yaml +174 -0
- package/package.json +6 -6
- package/src/servers/ZoneServer2016/managers/challengemanager.ts +23 -7
- package/src/servers/ZoneServer2016/managers/craftmanager.ts +25 -20
- package/src/servers/ZoneServer2016/managers/randomeventsmanager.ts +0 -2
- package/src/servers/ZoneServer2016/managers/worldobjectmanager.ts +10 -0
- package/src/servers/ZoneServer2016/zoneserver.ts +16 -1
package/config.yaml
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
server:
|
|
2
|
+
welcomeMessage: "Welcome to H1emu! :D"
|
|
3
|
+
adminMessage: "You are an Admin!"
|
|
4
|
+
proximityItemsDistance: 2
|
|
5
|
+
interactionDistance: 3
|
|
6
|
+
charactersRenderDistance: 350
|
|
7
|
+
tickRate: 2000
|
|
8
|
+
worldRoutineRate: 10000
|
|
9
|
+
enableLoginServerKickRequests: true
|
|
10
|
+
rebootTime: 48 # hours (0 to disable)
|
|
11
|
+
rebootWarnTime: 600 # seconds
|
|
12
|
+
isPvE: false
|
|
13
|
+
isHeadshotOnly: false
|
|
14
|
+
isFirstPersonOnly: false
|
|
15
|
+
isNoBuildInPois: true
|
|
16
|
+
baseConstructionDamage: 34000
|
|
17
|
+
|
|
18
|
+
# Rcon
|
|
19
|
+
|
|
20
|
+
rcon:
|
|
21
|
+
password: ""
|
|
22
|
+
port: 0
|
|
23
|
+
|
|
24
|
+
# VoiceChat
|
|
25
|
+
|
|
26
|
+
voicechat:
|
|
27
|
+
useVoiceChatV2: false
|
|
28
|
+
joinVoiceChatOnConnect: false
|
|
29
|
+
serverAccessToken: ""
|
|
30
|
+
|
|
31
|
+
# Fairplay / anticheat config
|
|
32
|
+
|
|
33
|
+
fairplay:
|
|
34
|
+
useFairplay: true
|
|
35
|
+
maxPing: 250
|
|
36
|
+
|
|
37
|
+
# Removing an entry below will allow clients with a certain rejectionFlag to join
|
|
38
|
+
# ex. Removing "5 # UNVERIFIED" will allow users with an unverified h1emu status to join
|
|
39
|
+
|
|
40
|
+
# by default, globally banned, hwid banned, vpn detected, and unverified clients will have their
|
|
41
|
+
# connections rejected
|
|
42
|
+
acceptedRejectionTypes:
|
|
43
|
+
# LOCAL_BAN, SERVER_LOCKED, and SERVER_REBOOT are always accepted
|
|
44
|
+
- 2 # GLOBAL_BAN
|
|
45
|
+
- 3 # VPN
|
|
46
|
+
- 4 # HWID
|
|
47
|
+
- 5 # UNVERIFIED
|
|
48
|
+
|
|
49
|
+
useAssetValidation: true
|
|
50
|
+
# how long the client has to send it's hashes before it's kicked (3 min default)
|
|
51
|
+
hashSubmissionTimeout: 180000
|
|
52
|
+
|
|
53
|
+
# clients with these packs are allowed to join, but they are optional (must be in numerical order)
|
|
54
|
+
allowedPacks:
|
|
55
|
+
#- file_name: ""
|
|
56
|
+
# crc32_hash: ""
|
|
57
|
+
|
|
58
|
+
# clients without these packs will be kicked (must be in numerical order)
|
|
59
|
+
requiredPacks:
|
|
60
|
+
#- file_name: ""
|
|
61
|
+
# crc32_hash: ""
|
|
62
|
+
|
|
63
|
+
weather:
|
|
64
|
+
defaultTemplate: "h1emubaseweather"
|
|
65
|
+
dynamicEnabled: true
|
|
66
|
+
|
|
67
|
+
# Anything to do with loot, vehicle, and npc spawning / despawning
|
|
68
|
+
worldobjects:
|
|
69
|
+
# Respawn timers
|
|
70
|
+
|
|
71
|
+
hasCustomLootRespawnTime: false
|
|
72
|
+
lootRespawnTimer: 1200000 # 30 minutes
|
|
73
|
+
vehicleRespawnTimer: 600000 # 10 minutes
|
|
74
|
+
npcRespawnTimer: 600000 # 10 minutes
|
|
75
|
+
|
|
76
|
+
# Despawn timers
|
|
77
|
+
|
|
78
|
+
# Player dropped items on the ground
|
|
79
|
+
itemDespawnTimer: 600000 # 10 minutes
|
|
80
|
+
# Spawned objects on the ground
|
|
81
|
+
lootDespawnTimer: 2400000 # 40 minutes
|
|
82
|
+
deadNpcDespawnTimer: 600000 # 10 minutes
|
|
83
|
+
lootbagDespawnTimer: 1800000 # 30 minutes
|
|
84
|
+
|
|
85
|
+
# Misc
|
|
86
|
+
minAirdropSurvivors: 10
|
|
87
|
+
vehicleSpawnCap: 120
|
|
88
|
+
# How far any other vehicle has to be for another to spawn
|
|
89
|
+
vehicleSpawnRadius: 50
|
|
90
|
+
# How far another spawned npc has to be for another to spawn
|
|
91
|
+
npcSpawnRadius: 3
|
|
92
|
+
chanceNpc: 100 # To be reworked: 100 max
|
|
93
|
+
chanceScreamer: 5 # To be reworked: 1000 max
|
|
94
|
+
|
|
95
|
+
chanceWornLetter: 1 # 100 max
|
|
96
|
+
|
|
97
|
+
waterSourceRefillAmount: 2
|
|
98
|
+
waterSourceReplenishTimer: 300000 # 5 minutes
|
|
99
|
+
|
|
100
|
+
crowbarHitRewardChance: 20 # 100 max
|
|
101
|
+
crowbarHitDamage: 10 # Default 25
|
|
102
|
+
|
|
103
|
+
# Trees, blackberry bushes, and sticks
|
|
104
|
+
speedtree:
|
|
105
|
+
minBlackberryHarvest: 1
|
|
106
|
+
maxBlackberryHarvest: 2
|
|
107
|
+
# from blackberry bushes only
|
|
108
|
+
branchHarvestChance: 0.1 # maximum of 1 for 100% chance
|
|
109
|
+
|
|
110
|
+
minStickHarvest: 1
|
|
111
|
+
maxStickHarvest: 2
|
|
112
|
+
|
|
113
|
+
treeRespawnTimeMS: 1800000 # 30 minutes
|
|
114
|
+
minWoodLogHarvest: 2
|
|
115
|
+
maxWoodLogHarvest: 6
|
|
116
|
+
minTreeHits: 12 # minimum hits it takes to chop a tree
|
|
117
|
+
maxTreeHits: 20 # maximum hits it takes to chop a tree
|
|
118
|
+
|
|
119
|
+
construction:
|
|
120
|
+
# allowPOIPlacement: false - deprecated in favor of isNoBuildInPOIs ^
|
|
121
|
+
allowStackedPlacement: false
|
|
122
|
+
allowOutOfBoundsPlacement: false
|
|
123
|
+
placementRange: 30
|
|
124
|
+
spawnPointBlockedPlacementRange: 25
|
|
125
|
+
vehicleSpawnPointBlockedPlacementRange: 30
|
|
126
|
+
playerFoundationBlockedPlacementRange: 70
|
|
127
|
+
playerShackBlockedPlacementRange: 20
|
|
128
|
+
|
|
129
|
+
decay:
|
|
130
|
+
decayTickInterval: 1200000 # 20 minutes per decay tick
|
|
131
|
+
constructionDamageTicks: 3 # damage structures every hour
|
|
132
|
+
|
|
133
|
+
# with default values it'll take 10 days for a base to fully decay
|
|
134
|
+
ticksToFullDecay: 240 # how many decay ticks * constructionDamageTicks it takes to fully decay any construction entity.
|
|
135
|
+
|
|
136
|
+
# unused for now but is planned
|
|
137
|
+
worldFreeplaceDecayMultiplier: 2 # used to multiply decay damage for freeplace constuction with no parent
|
|
138
|
+
|
|
139
|
+
##### DEPRECATED - NO LONGER DOES ANYTHING #####
|
|
140
|
+
baseConstructionDamage: 125000 # construction damage per required ticks
|
|
141
|
+
repairBoxHealValue: 1000000 # heals base to full condition
|
|
142
|
+
##### #####
|
|
143
|
+
|
|
144
|
+
vehicleDamageTicks: 3 # damage vehicles every hour
|
|
145
|
+
vacantFoundationTicks: 3 # destroy empty foundations after 1 hour
|
|
146
|
+
griefFoundationTimer: 72 # destroy grief foundations after 3 days (72 hours)
|
|
147
|
+
griefCheckSlotAmount: 4 # must have a minimum of 4 wall slots to avoid anti-grief
|
|
148
|
+
baseVehicleDamage: 2000 # 2% damage per 3 ticks (1 hour)
|
|
149
|
+
maxVehiclesPerArea: 2 # the max amount of vehicles that can be in an area before they start taking more damage
|
|
150
|
+
vehicleDamageRange: 25 # how large of a range to detect maxVehiclesPerArea
|
|
151
|
+
dailyRepairMaterials:
|
|
152
|
+
- itemDefinitionId: 16 # wood log
|
|
153
|
+
requiredCount: 1
|
|
154
|
+
- itemDefinitionId: 109 # wood plank
|
|
155
|
+
requiredCount: 10
|
|
156
|
+
- itemDefinitionId: 135 # nail
|
|
157
|
+
requiredCount: 4
|
|
158
|
+
- itemDefinitionId: 141 # metal bracket
|
|
159
|
+
requiredCount: 4
|
|
160
|
+
- itemDefinitionId: 46 # metal sheet
|
|
161
|
+
requiredCount: 1
|
|
162
|
+
- itemDefinitionId: 114 # metal shard
|
|
163
|
+
requiredCount: 8
|
|
164
|
+
- itemDefinitionId: 111 # wood stick
|
|
165
|
+
requiredCount: 2
|
|
166
|
+
|
|
167
|
+
smelting:
|
|
168
|
+
burnTime: 120000 # consume fuel every 120 seconds
|
|
169
|
+
smeltTime: 7000 # smelt 1 item every 7 seconds
|
|
170
|
+
gametime:
|
|
171
|
+
timeFrozen: false # Froze ingameTime
|
|
172
|
+
nightTimeMultiplier: 2 # This way night time pass 2 times faster than daytime
|
|
173
|
+
timeMultiplier: 36 # 1 hour IRL = 36 hours ingame, so 20 min for a full day
|
|
174
|
+
baseTime: 6 # server ingameTime start at 6 AM, 18 = 6PM
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h1z1-server",
|
|
3
|
-
"version": "0.45.0",
|
|
3
|
+
"version": "0.45.2-0",
|
|
4
4
|
"description": "Library for emulating h1z1 servers",
|
|
5
5
|
"author": "Quentin Gruber <quentingruber@gmail.com> (http://github.com/quentingruber)",
|
|
6
6
|
"license": "GPL-3.0-only",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@types/js-yaml": "4.0.9",
|
|
17
|
-
"@types/node": "22.
|
|
18
|
-
"@types/ws": "8.18.
|
|
17
|
+
"@types/node": "22.14.1",
|
|
18
|
+
"@types/ws": "8.18.1",
|
|
19
19
|
"debug": "4.4.0",
|
|
20
20
|
"h1emu-ai": "0.0.8",
|
|
21
21
|
"h1emu-core": "1.3.2",
|
|
@@ -24,19 +24,19 @@
|
|
|
24
24
|
"mongodb": "6.15.0",
|
|
25
25
|
"recast-navigation": "0.34.0",
|
|
26
26
|
"threads": "1.7.0",
|
|
27
|
-
"typescript": "5.8.
|
|
27
|
+
"typescript": "5.8.3",
|
|
28
28
|
"ws": "8.18.1"
|
|
29
29
|
},
|
|
30
30
|
"directories": {
|
|
31
31
|
"src": "./src"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"oxlint": "^0.16.3",
|
|
35
34
|
"cross-env": "^7.0.3",
|
|
36
35
|
"globals": "^16.0.0",
|
|
36
|
+
"oxlint": "^0.16.6",
|
|
37
37
|
"prettier": "^3.5.3",
|
|
38
38
|
"tsx": "^4.19.3",
|
|
39
|
-
"typedoc": "^0.28.
|
|
39
|
+
"typedoc": "^0.28.2"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"gen-packets-types": "tsx ./scripts/genPacketsNames.ts",
|
|
@@ -32,7 +32,9 @@ export enum ChallengeType {
|
|
|
32
32
|
GLOBAL_DISARMAMENT,
|
|
33
33
|
ROCKY,
|
|
34
34
|
ROCKSTAR,
|
|
35
|
-
IED
|
|
35
|
+
IED,
|
|
36
|
+
RANCHITO,
|
|
37
|
+
SWIZZLE
|
|
36
38
|
}
|
|
37
39
|
export enum ChallengeStatus {
|
|
38
40
|
CURRENT = 1,
|
|
@@ -102,6 +104,14 @@ export class ChallengeManager {
|
|
|
102
104
|
neededPoints: 1,
|
|
103
105
|
pvpOnly: false
|
|
104
106
|
},
|
|
107
|
+
{
|
|
108
|
+
type: ChallengeType.RANCHITO,
|
|
109
|
+
difficulty: ChallengeDifficulty.EASY,
|
|
110
|
+
name: "Wait... Why am i here again?",
|
|
111
|
+
description: "Visit Ranchito",
|
|
112
|
+
neededPoints: 1,
|
|
113
|
+
pvpOnly: false
|
|
114
|
+
},
|
|
105
115
|
{
|
|
106
116
|
type: ChallengeType.BRAIN_DEAD,
|
|
107
117
|
difficulty: ChallengeDifficulty.MEDIUM,
|
|
@@ -151,6 +161,14 @@ export class ChallengeManager {
|
|
|
151
161
|
neededPoints: 1,
|
|
152
162
|
pvpOnly: false
|
|
153
163
|
},
|
|
164
|
+
{
|
|
165
|
+
type: ChallengeType.SWIZZLE,
|
|
166
|
+
difficulty: ChallengeDifficulty.MEDIUM,
|
|
167
|
+
name: "Shady buisness",
|
|
168
|
+
description: "Consume some swizzle",
|
|
169
|
+
neededPoints: 1,
|
|
170
|
+
pvpOnly: false
|
|
171
|
+
},
|
|
154
172
|
{
|
|
155
173
|
type: ChallengeType.PV_PD_SURVIVAL,
|
|
156
174
|
difficulty: ChallengeDifficulty.HARD,
|
|
@@ -333,14 +351,12 @@ export class ChallengeManager {
|
|
|
333
351
|
}
|
|
334
352
|
|
|
335
353
|
async affectChallenge(client: ZoneClient2016) {
|
|
336
|
-
const today = new Date();
|
|
337
|
-
const timeZoneOffset = today.getTimezoneOffset() * 60000; // Convert minutes to milliseconds
|
|
338
354
|
const now = Date.now();
|
|
339
355
|
|
|
340
|
-
const startOfDay = new Date(now
|
|
356
|
+
const startOfDay = new Date(now);
|
|
341
357
|
startOfDay.setHours(0, 0, 0, 0);
|
|
342
358
|
|
|
343
|
-
const endOfDay = new Date(now
|
|
359
|
+
const endOfDay = new Date(now);
|
|
344
360
|
endOfDay.setHours(23, 59, 59, 999);
|
|
345
361
|
|
|
346
362
|
const challengesToday = await this.challengesCollection
|
|
@@ -371,8 +387,8 @@ export class ChallengeManager {
|
|
|
371
387
|
}
|
|
372
388
|
const challengesAvailable = this.challenges.filter((v) => {
|
|
373
389
|
return (
|
|
374
|
-
|
|
375
|
-
|
|
390
|
+
!challengesTypesDoneToday.includes(v.type) &&
|
|
391
|
+
(!v.pvpOnly || !this.server.isPvE) &&
|
|
376
392
|
v.difficulty === nextDifficultyChallenge
|
|
377
393
|
);
|
|
378
394
|
});
|
|
@@ -517,27 +517,32 @@ export class CraftManager {
|
|
|
517
517
|
client.character.lootItem(server, server.generateItem(id, 1));
|
|
518
518
|
});
|
|
519
519
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
520
|
+
switch (recipeId) {
|
|
521
|
+
case Items.IED:
|
|
522
|
+
server.challengeManager.registerChallengeProgression(
|
|
523
|
+
client,
|
|
524
|
+
ChallengeType.IED,
|
|
525
|
+
1
|
|
526
|
+
);
|
|
527
|
+
break;
|
|
528
|
+
|
|
529
|
+
case Items.FOUNDATION:
|
|
530
|
+
server.challengeManager.registerChallengeProgression(
|
|
531
|
+
client,
|
|
532
|
+
ChallengeType.MY_LAND,
|
|
533
|
+
1
|
|
534
|
+
);
|
|
535
|
+
break;
|
|
536
|
+
|
|
537
|
+
case Items.SHACK:
|
|
538
|
+
server.challengeManager.registerChallengeProgression(
|
|
539
|
+
client,
|
|
540
|
+
ChallengeType.MY_HOME,
|
|
541
|
+
1
|
|
542
|
+
);
|
|
543
|
+
break;
|
|
540
544
|
}
|
|
545
|
+
|
|
541
546
|
return true;
|
|
542
547
|
//#endregion
|
|
543
548
|
}
|
|
@@ -23,7 +23,6 @@ interface WeightedItem {
|
|
|
23
23
|
export class RandomEventsManager {
|
|
24
24
|
interval?: NodeJS.Timeout;
|
|
25
25
|
// managed by config
|
|
26
|
-
// TODO:
|
|
27
26
|
enabled: boolean = true;
|
|
28
27
|
constructor(public server: ZoneServer2016) {}
|
|
29
28
|
start() {
|
|
@@ -61,7 +60,6 @@ export class RandomEventsManager {
|
|
|
61
60
|
{ value: "Supplier", weight: 20 }
|
|
62
61
|
];
|
|
63
62
|
const airdropType = this.weightedRandom(airdropTypes);
|
|
64
|
-
console.log(airdropType);
|
|
65
63
|
this.server.spawnAirdrop(pos, airdropType);
|
|
66
64
|
const cellName = getCellName(cellIndex, 10);
|
|
67
65
|
this.server.sendAlertToAll(`Random airdrop on ${cellName}`);
|
|
@@ -523,6 +523,16 @@ export class WorldObjectManager {
|
|
|
523
523
|
effectTime: 60
|
|
524
524
|
}
|
|
525
525
|
);
|
|
526
|
+
|
|
527
|
+
if (
|
|
528
|
+
isPosInRadius(
|
|
529
|
+
3,
|
|
530
|
+
c.character.state.position,
|
|
531
|
+
server._airdrop.destinationPos
|
|
532
|
+
)
|
|
533
|
+
) {
|
|
534
|
+
server.killCharacter(c, { damage: 99999, entity: "aidrop" });
|
|
535
|
+
}
|
|
526
536
|
}
|
|
527
537
|
}
|
|
528
538
|
server._lootbags[characterId] = lootbag;
|
|
@@ -1948,7 +1948,10 @@ export class ZoneServer2016 extends EventEmitter {
|
|
|
1948
1948
|
const start = performance.now();
|
|
1949
1949
|
this.aiManager.run();
|
|
1950
1950
|
const end = performance.now();
|
|
1951
|
-
|
|
1951
|
+
const duration = end - start;
|
|
1952
|
+
if (duration >= 1) {
|
|
1953
|
+
console.log(`H1emu-ai took ${duration}ms`);
|
|
1954
|
+
}
|
|
1952
1955
|
} else {
|
|
1953
1956
|
this.aiManager.run();
|
|
1954
1957
|
}
|
|
@@ -4212,6 +4215,13 @@ export class ZoneServer2016 extends EventEmitter {
|
|
|
4212
4215
|
id: point.POIid
|
|
4213
4216
|
});
|
|
4214
4217
|
client.currentPOI = point.stringId;
|
|
4218
|
+
if (point.POIid === 13) {
|
|
4219
|
+
this.challengeManager.registerChallengeProgression(
|
|
4220
|
+
client,
|
|
4221
|
+
ChallengeType.RANCHITO,
|
|
4222
|
+
1
|
|
4223
|
+
);
|
|
4224
|
+
}
|
|
4215
4225
|
}
|
|
4216
4226
|
}
|
|
4217
4227
|
});
|
|
@@ -7379,6 +7389,11 @@ export class ZoneServer2016 extends EventEmitter {
|
|
|
7379
7389
|
sniffPass(client: Client, character: BaseFullCharacter, item: BaseItem) {
|
|
7380
7390
|
if (!this.removeInventoryItem(character, item)) return;
|
|
7381
7391
|
if (item.itemDefinitionId === Items.SWIZZLE) {
|
|
7392
|
+
this.challengeManager.registerChallengeProgression(
|
|
7393
|
+
client,
|
|
7394
|
+
ChallengeType.SWIZZLE,
|
|
7395
|
+
1
|
|
7396
|
+
);
|
|
7382
7397
|
this.applyMovementModifier(client, MovementModifiers.SWIZZLE);
|
|
7383
7398
|
} else {
|
|
7384
7399
|
this.applyMovementModifier(client, MovementModifiers.ADRENALINE);
|