-
-
Save MercerK/ed0b5721ddbb00ba0e38a0eb86363ef5 to your computer and use it in GitHub Desktop.
block state persistence
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Material } from '../../references' | |
import { ItemStoreMechanic } from '../item' | |
import { ItemKeys } from '../item/data' | |
import { createCustomItem, ItemUtil } from '../item/itemInstance' | |
import yaml from 'yaml' | |
const serializeChunk = (chunk: obChunk) => `${chunk.getX()},${chunk.getZ()}` | |
const LocationUtil = (arg: obbBlock) => { | |
const location = arg.getLocation() | |
function relativeToChunk(loc = location) { | |
return { | |
x: location.getX() & 0x000f, | |
y: location.getY() & 0x00ff, | |
z: location.getZ() & 0x000f, | |
} | |
} | |
function serializeRelativeToChunk() { | |
const { x, y, z } = relativeToChunk() | |
return `${x},${y},${z}` | |
} | |
function serializeChunk() { | |
const chunk = location.getChunk() | |
return `${chunk.getX()},${chunk.getZ()}` | |
} | |
return { | |
relativeToChunk, | |
serializeRelativeToChunk, | |
serializeChunk, | |
} | |
} | |
const Registry = <Registry extends Record<any, any>>() => { | |
let instances = [] | |
return (name: string, folder: string) => { | |
const path = `plugins/grakkit/data/server/${folder}/${name}.yml` | |
const file = core.file(path) | |
const registry: Record<string, Registry> = loadFile() | |
let length = 0 | |
function loadFile() { | |
let data = file.exists ? yaml.parse(file.read()) : {} | |
if (!file.exists) { | |
file.entry().write(yaml.stringify(data)) | |
} | |
length = getLength(data) | |
if (length > 0) console.log(`Loading ${length} items`) | |
return data | |
} | |
function saveFile() { | |
file.write(yaml.stringify(registry)) | |
} | |
function get(key: string) { | |
return registry[key] | |
} | |
function set(key: string, value: Registry) { | |
if (!registry[key]) length++ | |
registry[key] = value | |
saveFile() | |
} | |
function has(key: string) { | |
return registry[key] !== undefined | |
} | |
function unset(key: string) { | |
length-- | |
delete registry[key] | |
} | |
function getLength(data = registry) { | |
return Object.keys(data).length | |
} | |
function toString() { | |
return JSON.stringify(registry) | |
} | |
return { | |
get, | |
set, | |
has, | |
unset, | |
getLength, | |
toString, | |
toJSON: toString, | |
} | |
} | |
} | |
const BlockRegistry = Registry<{ | |
placed: string | |
itemId: ItemKeys | |
}>() | |
const ChunkRegistry = Registry<{ | |
blocks: ReturnType<typeof BlockRegistry> | |
}>() | |
const WorldRegistry = Registry<{ | |
chunks: ReturnType<typeof ChunkRegistry> | |
}>() | |
export class BlockStorage { | |
static registry = ChunkRegistry('chunks', '') | |
static initializeEvents() { | |
// Unload Chunks | |
core.event('org.bukkit.event.world.ChunkUnloadEvent', (event) => { | |
const serializedChunk = serializeChunk(event.getChunk()) | |
if (BlockStorage.registry.has(serializedChunk)) { | |
BlockStorage.registry.unset(serializedChunk) | |
console.log(`[Verbose] Unloading Chunk ${serializeChunk(event.getChunk())}`) | |
} | |
}) | |
// Adds to Registry | |
core.event('org.bukkit.event.block.BlockPlaceEvent', (event) => { | |
const block = event.getBlock() | |
const item = event.getItemInHand() | |
if (block.getType() !== Material.PLAYER_HEAD && block.getType() !== Material.PLAYER_WALL_HEAD) | |
return | |
const itemId = ItemUtil(item).getItemId() | |
if (!itemId) return | |
BlockStorage.setBlock(block, itemId) | |
}) | |
// Removes block from registry and drops correct item | |
core.event('org.bukkit.event.block.BlockBreakEvent', (event) => { | |
const block = event.getBlock() | |
if (block.getType() !== Material.PLAYER_HEAD && block.getType() !== Material.PLAYER_WALL_HEAD) | |
return | |
const state = BlockStorage.getBlock(block) | |
if (!state) return | |
const { itemId } = state | |
const customItem = ItemStoreMechanic.getItem(itemId) | |
if (!customItem) return | |
event.setDropItems(false) | |
block.getWorld().dropItem(block.getLocation(), createCustomItem(customItem)) | |
}) | |
} | |
private static getBlock(block: obbBlock) { | |
const util = LocationUtil(block) | |
const serializedChunk = util.serializeChunk() | |
const chunk = BlockStorage.registry.get(serializedChunk) | |
if (!chunk) return | |
const serializedBlock = util.serializeRelativeToChunk() | |
if (!chunk.blocks.get) { | |
chunk.blocks = BlockRegistry(serializedChunk, 'chunks') | |
} | |
const blockState = chunk.blocks.get(serializedBlock) | |
chunk.blocks.unset(serializedBlock) | |
return blockState | |
} | |
private static setBlock(block: obbBlock, itemId: ItemKeys) { | |
const util = LocationUtil(block) | |
const serializedChunk = util.serializeChunk() | |
let chunk = BlockStorage.registry.get(serializedChunk) | |
if (!chunk) { | |
BlockStorage.registry.set(serializedChunk, { | |
blocks: BlockRegistry(serializedChunk, 'chunks'), | |
}) | |
chunk = BlockStorage.registry.get(serializedChunk) | |
} | |
if (!chunk.blocks.get) { | |
chunk.blocks = BlockRegistry(serializedChunk, 'chunks') | |
} | |
chunk.blocks.set(LocationUtil(block).serializeRelativeToChunk(), { | |
placed: new Date().toISOString(), | |
itemId, | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment