-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added WSS functions - Added dots materials
- Loading branch information
1 parent
13b2fe1
commit 39cf83b
Showing
16 changed files
with
358 additions
and
85 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,10 +10,11 @@ | |
"canvas/": "https://deno.land/x/[email protected]/", | ||
"culori": "https://deno.land/x/[email protected]/index.js", | ||
"case/": "https://deno.land/x/[email protected]/", | ||
"path/": "https://deno.land/[email protected]/path/", | ||
"fs/": "https://deno.land/[email protected]/fs/", | ||
"fmt/": "https://deno.land/[email protected]/fmt/", | ||
"log/": "https://deno.land/[email protected]/log/", | ||
"path/": "https://deno.land/[email protected]/path/", | ||
"fs/": "https://deno.land/[email protected]/fs/", | ||
"fmt/": "https://deno.land/[email protected]/fmt/", | ||
"log/": "https://deno.land/[email protected]/log/", | ||
"http/": "https://deno.land/[email protected]/http/", | ||
"deno_markdown/": "https://deno.land/x/[email protected]/", | ||
"@minecraft/server": "npm:@minecraft/server@^1.0.0-beta.release.1.19.40" | ||
} | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
import type { Axis, WssParams, WssState } from "./typings/types.ts"; | ||
import { decode } from "./src/components/ImagePrinter.ts"; | ||
import assemble from "./src/components/_assemble.ts"; | ||
import { serve } from "https://deno.land/[email protected]/http/server.ts"; | ||
import { join } from "https://deno.land/[email protected]/path/win32.ts"; | ||
import { ensureDir } from "https://deno.land/[email protected]/fs/mod.ts"; | ||
import { serve } from "http/server.ts"; | ||
import { join } from "path/win32.ts"; | ||
import { ensureDir } from "fs/mod.ts"; | ||
|
||
type SubscribeEvents = | ||
| "AdditionalContentLoaded" | ||
|
@@ -105,6 +103,7 @@ const state: WssState = { | |
offset: [8, 0, -16], | ||
useAbsolutePosition: false, | ||
axis: "x" as Axis, | ||
enableBlockHistory: false, | ||
blockHistory: [], | ||
blockHistoryMaxLength: 500, | ||
functionLog: join(Deno.cwd(), 'build', 'wss', 'functions') | ||
|
@@ -131,9 +130,7 @@ const formatPosition = (x: number, y: number, z: number, offsetX?: number, offse | |
return useAbsolutePosition ? `${nx} ${ny} ${nz}` : `~${nx} ~${ny} ~${nz}`; | ||
}; | ||
|
||
function getBlockLibrary(material: string, exclude?: string[]) { | ||
return assemble(exclude).filter((b) => b.behaviorId.includes(material)); | ||
} | ||
|
||
|
||
let connectionUpdateInterval: number | undefined; | ||
|
||
|
@@ -185,6 +182,15 @@ async function processMessage( | |
|
||
// TODO: Add index help function | ||
|
||
if (contents.startsWith("history/")) { | ||
const steps = parseInt(contents.replace("history/", ""), 10); | ||
|
||
state.blockHistory = []; | ||
state.enableBlockHistory = steps > 0; | ||
state.blockHistoryMaxLength = steps; | ||
return; | ||
} | ||
|
||
// Live reload | ||
if (contents.startsWith("lr/")) { | ||
await watch(contents.replace("lr/", "").trim()); | ||
|
@@ -211,36 +217,6 @@ async function processMessage( | |
return; | ||
} | ||
|
||
if (contents.startsWith("axis/")) { | ||
state.axis = contents.replace("axis/", "").trim() as Axis; | ||
console.info("Axis set to %s", state.axis); | ||
return; | ||
} | ||
|
||
if (contents.startsWith("https://") || contents.startsWith("http://")) { | ||
console.info("Image URL updated to", contents); | ||
updateContent(contents); | ||
return; | ||
} | ||
|
||
if (contents.startsWith("material/")) { | ||
const material = contents.replace("material/", "").replace(/\s+/g, "_"); | ||
state.material = material; | ||
console.info("Material updated to", material); | ||
return; | ||
} | ||
|
||
if (contents.startsWith("position/")) { | ||
const position = contents.replace("position/", "").split(/[\s,]+/g, 3).map( | ||
(v) => parseInt(v, 10), | ||
).slice(0, 3) as [number, number, number]; | ||
|
||
state.offset = position; | ||
state.useAbsolutePosition = true; | ||
console.info("Position updated to %o", position); | ||
return; | ||
} | ||
|
||
if (contents.startsWith("log/") && state.functionLog) { | ||
const fn = contents.replace("log/", "").trim(); | ||
|
||
|
@@ -305,15 +281,7 @@ async function updateContent(imgUrl: string) { | |
} | ||
|
||
state.updatePending = true; | ||
const commands = await decode( | ||
new URL(imgUrl), | ||
getBlockLibrary(state.material ?? "plastic_50"), | ||
state.offset ?? [0, 0, 0], | ||
state.axis, | ||
state.useAbsolutePosition === true, | ||
); | ||
requests.length = 0; | ||
commands.map((c) => queueCommandRequest(c)); | ||
|
||
console.info("Queued %d commands", commands.length); | ||
state.updatePending = false; | ||
} | ||
|
@@ -359,7 +327,7 @@ function queueCommandRequest(commandLine: string) { | |
result: false, | ||
}); | ||
|
||
// sessionStorage.setItem(`request[${uuid}]`, content); | ||
//sessionStorage.setItem(`request[${uuid}]`, content); | ||
|
||
// Speed up rend rate based on number of requests | ||
state.sendRate = requests.length > 100 ? 3 : 1; | ||
|
@@ -376,7 +344,7 @@ async function onOpenHandler(socket: WebSocket) { | |
|
||
if ( | ||
(requestsCount === 0 && !state.updatePending) || | ||
requests[state.currentRequestIdx].result | ||
requests[state.currentRequestIdx]?.result | ||
) { | ||
return; | ||
} | ||
|
@@ -413,7 +381,7 @@ function processCommandResponse(msg: { body: any, header: any }) { | |
return; | ||
} | ||
|
||
if (msg.body.statusMessage === "Block placed" && msg.body.position) { | ||
if (state.enableBlockHistory === true && msg.body.statusMessage === "Block placed" && msg.body.position) { | ||
const pos = Object.values(msg.body.position).map((v) => parseInt(`${v}`, 10)).slice(0, 3) as [number, number, number]; | ||
sessionStorage.setItem("lastBlock", JSON.stringify(pos)); | ||
|
||
|
@@ -435,9 +403,9 @@ function processCommandResponse(msg: { body: any, header: any }) { | |
|
||
delete requests[idx]; | ||
|
||
//const pendingRequest = requests.find((r) => r.uuid === msg.header.requestId); | ||
// const pendingRequest = requests.find((r) => r.uuid === msg.header.requestId); | ||
|
||
//const sessionData = sessionStorage.getItem(`request[${msg.body.requestId}]`); | ||
// const sessionData = sessionStorage.getItem(`request[${msg.body.requestId}]`); | ||
|
||
// if (pendingRequest) { | ||
// pendingRequest.result = true; | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
import type { Axis } from "../../typings/types.ts"; | ||
import { decode as decodeImage, Frame, GIF, Image } from "imagescript/mod.ts"; | ||
import { extname, join } from "https://deno.land/[email protected]/path/mod.ts"; | ||
import { sprintf } from "https://deno.land/[email protected]/fmt/printf.ts"; | ||
import { EOL } from "https://deno.land/[email protected]/fs/mod.ts"; | ||
import { type Frame, GIF, Image } from "imagescript/mod.ts"; | ||
import { extname, join } from "path/mod.ts"; | ||
import { sprintf } from "fmt/printf.ts"; | ||
import { EOL } from "fs/mod.ts"; | ||
import { materials } from "../store/_materials.ts"; | ||
import BlockEntry from "./BlockEntry.ts"; | ||
import { DIR_BP } from "../store/_config.ts"; | ||
import { BLOCK_VERSION, DIR_BP } from "../store/_config.ts"; | ||
import { hex2rgb } from "https://crux.land/3RdawE"; | ||
|
||
//import { encode, Int } from "https://deno.land/x/[email protected]/mod.ts"; | ||
//import { encode, Int, stringify } from "npm:[email protected]"; | ||
// import * as nbt from "npm:[email protected]"; | ||
import type { IMaterial, RGB } from "../../typings/types.ts"; | ||
|
||
const MAX_PRINT_SIZE = 3 * 16; | ||
|
@@ -17,6 +19,7 @@ const MASK_COLOR = [ | |
]; // Image.rgbToColor(...hex2rgb("#ff00ff")); | ||
const FUNCTIONS_NAMESPACE = "printer"; | ||
const DIR_FUNCTIONS = join(DIR_BP, "functions", FUNCTIONS_NAMESPACE); | ||
const DIR_STRUCTURES = join(DIR_BP, "structures"); | ||
|
||
function colorDistance(color1: RGB, color2: RGB) { | ||
return Math.sqrt( | ||
|
@@ -25,6 +28,112 @@ function colorDistance(color1: RGB, color2: RGB) { | |
); | ||
} | ||
|
||
// export function createStructureTag() { | ||
// const block_palette: Array<CompoundTag> = []; | ||
// return { | ||
// format_version: new Int(1), | ||
// size: [1, 1, 1] as ListTag<IntTag>, | ||
// structure_world_origin: [0, 0, 0] as ListTag<IntTag>, | ||
// structure: { | ||
// block_indices: [[0, 0, 0], [ | ||
// -1, | ||
// -1, | ||
// -1, | ||
// ]] as ListTag<ListTag<IntTag>>, | ||
// entities: [] as ListTag<CompoundTag>, | ||
// palette: { | ||
// default: { | ||
// block_palette, | ||
// block_position_data: {}, | ||
// }, | ||
// }, | ||
// }, | ||
// }; | ||
// } | ||
|
||
// function placeBlock(name: string, version = 17825806) { | ||
// return | ||
// } | ||
|
||
export async function constructDecoded( | ||
name: string, | ||
frames: GIF | Array<Image | Frame>, | ||
palette: BlockEntry[], | ||
) { | ||
const frameCount = frames.length; | ||
const positionData = []; | ||
const layer = []; | ||
const waterLayer = []; | ||
let idx = 0; | ||
|
||
let xDim = 0; | ||
let yDim = 0; | ||
|
||
const blockPalette = []; | ||
|
||
for (let z = 0; z < frameCount; z++) { | ||
const img = frames[z]; | ||
|
||
for (const [x, y, c] of img.iterateWithColors()) { | ||
const nearest = | ||
getNearestColor(<RGB> Image.colorToRGB(c), palette)?.behaviorId ?? | ||
"minecraft:cobblestone"; | ||
layer.push(z, Math.abs(y - img.height), x); | ||
waterLayer.push(-1, -1, -1); | ||
|
||
blockPalette.push( | ||
{ | ||
version: BLOCK_VERSION, | ||
name: nearest, | ||
//states: nbt.comp({}), | ||
}, | ||
); | ||
|
||
positionData.push([idx, { | ||
block_entity_data: {}, | ||
}]); | ||
|
||
xDim = Math.max(xDim, x); | ||
yDim = Math.max(yDim, y); | ||
idx++; | ||
} | ||
} | ||
|
||
const tag = { | ||
format_version: 1, | ||
size: [ | ||
xDim, | ||
yDim, | ||
frameCount, | ||
], | ||
structure_world_origin: [0, 0, 0], | ||
structure: { | ||
block_indices: [layer, waterLayer], | ||
//entities: nbt.list([]), | ||
palette: { | ||
default: { | ||
block_palette: blockPalette, | ||
block_position_data: Object | ||
.fromEntries( | ||
positionData, | ||
), | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const encoder = new TextEncoder(); | ||
const enc = encoder.encode(JSON.stringify(tag)); | ||
|
||
await Deno.writeFile( | ||
join( | ||
DIR_STRUCTURES, | ||
`${name}.mcstructure`, | ||
), | ||
new Uint8Array(new Uint16Array(enc).buffer), | ||
); | ||
} | ||
|
||
export function getNearestColor( | ||
color: RGB, | ||
palette: BlockEntry[], | ||
|
@@ -58,20 +167,34 @@ function writeFill( | |
return `fill ${position} ${position} ${fillWith} 0 keep`; | ||
} | ||
|
||
/** | ||
* @deprecated | ||
*/ | ||
export async function decode( | ||
src: URL, | ||
palette: BlockEntry[], | ||
offset: number[], | ||
axis: Axis = "z", | ||
absolutePosition = false, | ||
resize?: number, | ||
): Promise<string[]> { | ||
// TODO: Add 10000 line limit | ||
const imgSrc = await decodeImage( | ||
await (await fetch(src)).arrayBuffer(), | ||
true, | ||
); | ||
const img = imgSrc instanceof GIF ? imgSrc[0] : imgSrc; | ||
const img = (await decodeUrl(src))[0]; | ||
|
||
if (resize) { | ||
img.resize(resize, resize); | ||
} | ||
|
||
return convertImage(img, palette, offset, axis, absolutePosition); | ||
} | ||
|
||
export function convertImage( | ||
img: Image | Frame, | ||
palette: BlockEntry[], | ||
offset: number[], | ||
axis: Axis = "z", | ||
absolutePosition = false, | ||
): string[] { | ||
const func: string[] = []; | ||
|
||
for (const [x, y, c] of img.iterateWithColors()) { | ||
|
@@ -158,18 +281,25 @@ async function printDecoded( | |
); | ||
} | ||
|
||
export async function decodeUrl({ href }: URL): Promise<GIF | Image[]> { | ||
const res = await fetch(href); | ||
const data = new Uint8Array(await res.arrayBuffer()); | ||
|
||
return (extname(href) !== ".gif") | ||
? [await Image.decode(data)] | ||
: (await GIF.decode(data, false)); | ||
} | ||
|
||
/** | ||
* @deprecated | ||
*/ | ||
export async function pixelPrinter( | ||
name: string, | ||
imageUrl: URL, | ||
palette: BlockEntry[], | ||
chunks = 2, | ||
) { | ||
const res = await fetch(imageUrl.href); | ||
const data = new Uint8Array(await res.arrayBuffer()); | ||
|
||
const frames = (extname(imageUrl.href) !== ".gif") | ||
? [await Image.decode(data)] | ||
: (await GIF.decode(data, false)); | ||
const frames = await decodeUrl(imageUrl); | ||
|
||
const size = Math.min(MAX_PRINT_SIZE, chunks * 16); | ||
|
||
|
Oops, something went wrong.