Skip to content

Commit

Permalink
still not making correct hashes
Browse files Browse the repository at this point in the history
  • Loading branch information
InventivetalentDev committed Aug 28, 2024
1 parent f970bc3 commit 6e98a9c
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 24 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ version = "0.0.0"
crate-type = ["cdylib"]

[dependencies]
lodepng = "3.10.4"
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.12.2", default-features = false, features = ["napi4"] }
napi-derive = "2.12.2"
sha2 = "0.10.8"

lodepng = { version = "3.7.0", default-features = false }
flate2 = { package = "flate2", version = "1.0.24", features = ["zlib"], default-features = false }
rgb = "0.8.34"
sha2 = "0.10.6"

[build-dependencies]
napi-build = "2.0.1"
Expand Down
19 changes: 17 additions & 2 deletions __test__/index.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import test from 'ava'

import { sum } from '../index.js'
import { sum, encodeImage } from '../index.js'
import * as fs from "node:fs";

test('sum from native', (t) => {
t.is(sum(1, 2), 3)
t.is(sum(1, 2), 3)
})

test('encode random 1', t => {
let buffer = fs.readFileSync('images/6a12c0010c6e708422f5ba5121ba4a8adc9c7374c2b96fd0754c84f25e181598.png');
let arr = new Uint8Array(buffer);
let encoded = encodeImage(arr);

let hash = Buffer.from(encoded.hash).toString('hex');
console.log(hash);

let mchash = Buffer.from(encoded.minecraftHash).toString('hex');
console.log(mchash);

console.log(encoded.hex)
})
9 changes: 5 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
/* auto-generated by NAPI-RS */

export declare function sum(a: number, b: number): number
export declare function encodeImage(rawData: Uint8Array): ImageWithHashes
export declare function encodeImage(buffer: Uint8Array): ImageWithHashes
export declare class ImageWithHashes {
png: Uint8Array
minecraftHash: Uint8Array
hash: Uint8Array
png: Buffer
minecraftHash: Buffer
hash: Buffer
hex: string
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"license": "MIT",
"devDependencies": {
"@napi-rs/cli": "^2.18.4",
"ava": "^6.0.1"
"ava": "^6.0.1",
"canvas": "^2.11.2"
},
"ava": {
"timeout": "3m"
Expand Down
37 changes: 37 additions & 0 deletions randomImage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require('fs');
const {createCanvas, loadImage} = require("canvas");

function makeRandomImage(width = 64, height = 64) {
const canvas = createCanvas(width, height);
const context = canvas.getContext("2d");
const imageData = context.getImageData(0, 0, width, height);

// https://gist.github.com/biovisualize/5400576#file-index-html-L26
const buffer = new ArrayBuffer(imageData.data.length);
const clampedBuffer = new Uint8ClampedArray(buffer);
const data = new Uint32Array(buffer);

for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
data[y * width + x] =
(255 << 24) |
(((Math.random() * 300) % 255) << 16) |
(((Math.random() * 300) % 255) << 8) |
(((Math.random() * 300) % 255))
}
}

imageData.data.set(clampedBuffer);
context.putImageData(imageData, 0, 0);

// Make Buffer
const dataUrl = canvas.toDataURL("image/png").substr("data:image/png;base64,".length);
const imageBuffer = new Buffer(dataUrl, 'base64');
const blob = new Blob([imageBuffer], { type: "image/png" });
return { imageBuffer, imageData, data, blob }
}

(() => {
const { imageBuffer, imageData, data, blob } = makeRandomImage(64, 64);
fs.writeFileSync('images/randomImage.png', imageBuffer);
})();
49 changes: 36 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![deny(clippy::all)]

use lodepng::FilterStrategy;
use lodepng::{FilterStrategy, RGBA};
use sha2::{Digest, Sha256};
use napi::{
bindgen_prelude::{Buffer, ClassInstance, ObjectFinalize, This, Uint8Array, Unknown},
Expand All @@ -22,41 +22,64 @@ pub fn sum(a: i32, b: i32) -> i32 {

#[napi]
pub struct ImageWithHashes {
pub png: Uint8Array,
pub minecraft_hash: Uint8Array,
pub hash: Uint8Array,
pub png: Buffer,
pub minecraft_hash: Buffer,
pub hash: Buffer,
pub hex: String,
}

#[napi]
pub fn encode_image(raw_data: &[u8]) -> ImageWithHashes {
encode_custom_image(raw_data, SKIN_WIDTH, SKIN_HEIGHT)
pub fn encode_image(buffer: &[u8]) -> ImageWithHashes {
encode_custom_image(buffer, SKIN_WIDTH as usize, SKIN_HEIGHT as usize)
}

// based on https://github.com/GeyserMC/global_api/blob/dev/1.0.2/native/skins/src/skin_convert/skin_codec.rs#L100
//#[napi]
pub fn encode_custom_image(raw_data: &[u8], width: u8, height: u8) -> ImageWithHashes {
pub fn encode_custom_image(buffer: &[u8], width: usize, height: usize) -> ImageWithHashes {
let mut raw_data = vec![0; width * height * SKIN_CHANNELS as usize];
buffer.iter().enumerate().for_each(|(i, byte)| {
raw_data[i] = *byte;
});

// encode images like Minecraft does
let mut encoder = lodepng::Encoder::new();
encoder.set_auto_convert(false);
encoder.info_png_mut().interlace_method = 0; // should be 0 but just to be sure

let mut encoder_settings = encoder.settings_mut();
let encoder_settings = encoder.settings_mut();
encoder_settings.zlibsettings.set_level(4);
encoder_settings.filter_strategy = FilterStrategy::ZERO;

let png = encoder.encode(raw_data, width as usize, height as usize).unwrap();
println!("Encoding image with width: {}, height: {}", width, height);
println!("Raw data length: {}", raw_data.len());

let result = encoder.encode(&raw_data, width, height);
println!("Result: {:?}", result);
let png = result.unwrap();

let mut hasher = Sha256::new();

hasher.update(&png);
let minecraft_hash = hasher.finalize_reset();

// make our own hash
hasher.update(raw_data);
hasher.update(&raw_data);
let hash = hasher.finalize();

let hex = write_hex(minecraft_hash.as_ref());

ImageWithHashes {
png: Uint8Array::from(png.as_slice()),
minecraft_hash: Uint8Array::from(minecraft_hash.as_slice()),
hash: Uint8Array::from(hash.as_slice()),
png: Buffer::from(png.as_slice()),
minecraft_hash: Buffer::from(minecraft_hash.as_slice()),
hash: Buffer::from(hash.as_slice()),
hex: hex
}
}

fn write_hex(bytes: &[u8]) -> String {
let mut s = String::with_capacity(2 * bytes.len());
for byte in bytes {
core::fmt::write(&mut s, format_args!("{:02X}", byte)).unwrap();
}
s
}
44 changes: 42 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# yarn lockfile v1


"@mapbox/node-pre-gyp@^1.0.5":
"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.5":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa"
integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==
Expand Down Expand Up @@ -248,6 +248,15 @@ callsites@^4.1.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-4.2.0.tgz#98761d5be3ce092e4b9c92f7fb8c8eb9b83cadc8"
integrity sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==

canvas@^2.11.2:
version "2.11.2"
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860"
integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.0"
nan "^2.17.0"
simple-get "^3.0.3"

cbor@^9.0.1:
version "9.0.2"
resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.2.tgz#536b4f2d544411e70ec2b19a2453f10f83cd9fdb"
Expand Down Expand Up @@ -376,6 +385,13 @@ debug@4, debug@^4.3.4:
dependencies:
ms "2.1.2"

decompress-response@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
dependencies:
mimic-response "^2.0.0"

delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
Expand Down Expand Up @@ -713,6 +729,11 @@ mimic-function@^5.0.0:
resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076"
integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==

mimic-response@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==

minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
Expand Down Expand Up @@ -755,6 +776,11 @@ ms@^2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==

nan@^2.17.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3"
integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==

node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
Expand Down Expand Up @@ -794,7 +820,7 @@ object-assign@^4.1.1:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==

once@^1.3.0:
once@^1.3.0, once@^1.3.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
Expand Down Expand Up @@ -940,6 +966,20 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==

simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==

simple-get@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55"
integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==
dependencies:
decompress-response "^4.2.0"
once "^1.3.1"
simple-concat "^1.0.0"

slash@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
Expand Down

0 comments on commit 6e98a9c

Please sign in to comment.