Skip to content

Commit

Permalink
Make created level.dat loadable in singleplayer (#71)
Browse files Browse the repository at this point in the history
* make created worlds loadable in singleplayer

* add typings field

* make typings valid (no typechecking because of not tsconfig)
  • Loading branch information
zardoy authored Dec 17, 2023
1 parent f3881cb commit 2638bec
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "2.7.0",
"description": "Anvil Storage Provider implementation.",
"main": "index.js",
"typings": "src/index.d.ts",
"scripts": {
"test": "mocha test/",
"pretest": "npm run lint",
Expand Down
3 changes: 3 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const Anvil: typeof import('./anvil')
export const chunk: typeof import('./chunk')
export const level: typeof import('./level')
168 changes: 168 additions & 0 deletions src/level.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// readLevel, writeLevel

// 1.8.8
export interface LevelDatFull {
WorldGenSettings?: WorldGenSettings;
RandomSeed: number[];
generatorName?: string;
BorderCenterX: number;
BorderCenterZ: number;
Difficulty: number;
DifficultyLocked: number;
BorderSizeLerpTime: number[];
Version?: {
Name: string
// id, snapshot
}
/** 0,1 */
raining: number;
Time: number[];
GameType: number;
MapFeatures: number;
BorderDamagePerBlock: number;
BorderWarningBlocks: number;
BorderSizeLerpTarget: number;
DayTime: number[];
initialized: number;
allowCommands: number;
SizeOnDisk: number[];
GameRules: GameRules;
Player: Player;
SpawnY: number;
rainTime: number;
thunderTime: number;
SpawnZ: number;
hardcore: number;
SpawnX: number;
clearWeatherTime: number;
thundering: number;
generatorVersion?: number;
version: number;
BorderSafeZone: number;
generatorOptions?: string;
LastPlayed: number[];
BorderWarningTime: number;
LevelName: string;
BorderSize: number;
}

export interface GameRules {
doTileDrops: string;
doFireTick: string;
reducedDebugInfo: string;
naturalRegeneration: string;
doMobLoot: string;
keepInventory: string;
doEntityDrops: string;
mobGriefing: string;
randomTickSpeed: string;
commandBlockOutput: string;
doMobSpawning: string;
logAdminCommands: string;
sendCommandFeedback: string;
doDaylightCycle: string;
showDeathMessages: string;
}

export interface Player {
HurtByTimestamp: number;
SleepTimer: number;
Attributes: Attribute[];
Invulnerable: number;
PortalCooldown: number;
AbsorptionAmount: number;
abilities: Abilities;
FallDistance: number;
DeathTime: number;
XpSeed: number;
HealF: number;
XpTotal: number;
playerGameType: number;
SelectedItem: SelectedItem;
Motion: number[];
UUIDLeast: number[];
Health: number;
foodSaturationLevel: number;
Air: number;
OnGround: number;
Dimension: number;
Rotation: number[];
XpLevel: number;
Score: number;
UUIDMost: number[];
Sleeping: number;
Pos: number[];
Fire: number;
XpP: number;
EnderItems: any[];
foodLevel: number;
foodExhaustionLevel: number;
HurtTime: number;
SelectedItemSlot: number;
Inventory: SelectedItem[];
foodTickTimer: number;
}

export interface Attribute {
Base: number;
Name: string;
}

export interface SelectedItem {
Slot?: number;
id: string;
Count: number;
Damage: number;
}

export interface Abilities {
invulnerable: number;
mayfly: number;
instabuild: number;
walkSpeed: number;
mayBuild: number;
flying: number;
flySpeed: number;
}

// 1.16+

export interface WorldGenSettings {
/** 0,1 */
bonus_chest: number;
seed: number[];
/** 0,1 */
generate_features: number;
dimensions: Dimensions;
}

export interface Dimensions {
// :overworld, :the_nether, :the_end
[key: string]: WorldGen;
}

export interface WorldGen {
generator: WorldGenGenerator;
// same as key
type: string;
}

export interface WorldGenGenerator {
settings: string;
seed: number[];
biome_source: BiomeSource;
type: string;
}

export interface BiomeSource {
seed: number[];
/** only for overworld 0,1 */
large_biomes?: number;
// :noise, :flat, ?
type: string;
}

export type LevelDatWrite = Pick<LevelDatFull, 'RandomSeed' | 'Version' | 'generatorName'>

export function readLevel(path: string): Promise<LevelDatFull>
export function writeLevel(path: string, value: LevelDatWrite): Promise<void>
22 changes: 22 additions & 0 deletions src/level.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ async function writeLevel (path, value) {
Data: {
type: 'compound',
value: {
// ...oldLevel.value?.Data?.value,
Version: {
type: 'compound',
value: {
Name: {
type: 'string',
value: value.Version.Name
}
}
},
LevelName: {
type: 'string',
value: 'prismarine-world'
},
generatorName: {
type: 'string',
value: value.generatorName
},
version: {
type: 'int',
value: 19133
},
RandomSeed: {
type: 'long',
value: value.RandomSeed
Expand Down

0 comments on commit 2638bec

Please sign in to comment.