-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Danny Schumacher
committed
Jan 6, 2020
0 parents
commit 6c368f1
Showing
42 changed files
with
15,148 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.gitignore | ||
.vscode | ||
README.md | ||
node_modules | ||
dist | ||
out |
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
PORT=3030 | ||
|
||
#read 4 bits instead of 3 for stash | ||
EXTENDED_STASH=true | ||
|
||
#where are saves | ||
SAVE_DIR=/mnt/d/Git/d2/113c/d2s/save | ||
#SAVE_DIR=/Users/drschuma/Documents/d2/113c/d2s/save | ||
|
||
#mpq data. txt files, images, and palette data | ||
MPQ_DATA_DIR=/mnt/d/Git/d2/113c/data | ||
#MPQ_DATA_DIR=/Users/drschuma/Documents/d2/113c/data | ||
|
||
#optional img directory if different than mpq | ||
#IMG_DATA_DIR=/Users/drschuma/Documents/d2/113c/data | ||
|
||
VUE_APP_TITLE=D2S-UI | ||
|
||
#VUE_APP_INV_WIDTH=10 | ||
#VUE_APP_INV_HEIGHT=4 | ||
|
||
#VUE_APP_STASH_WIDTH=10 | ||
#VUE_APP_STASH_HEIGHT=10 | ||
|
||
#VUE_APP_CUBE_WIDTH=5 | ||
#VUE_APP_CUBE_HEIGHT=5 |
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 |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module.exports = { | ||
root: true, | ||
env: { | ||
node: true, | ||
}, | ||
extends: [ | ||
'plugin:vue/essential', | ||
'@vue/airbnb', | ||
], | ||
rules: { | ||
'no-param-reassign': [2, { props: false }], | ||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', | ||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', | ||
}, | ||
parserOptions: { | ||
parser: 'babel-eslint', | ||
}, | ||
}; |
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 |
---|---|---|
@@ -0,0 +1,25 @@ | ||
.DS_Store | ||
node_modules | ||
/dist | ||
/out | ||
|
||
build.js | ||
|
||
# local env files | ||
.env.local | ||
.env.*.local | ||
|
||
# Log files | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Editor directories and files | ||
.idea | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? | ||
|
||
|
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 |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "node", | ||
"request": "launch", | ||
"name": "Launch Program", | ||
"args": ["${workspaceRoot}/app.ts"], | ||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"], | ||
"sourceMaps": true, | ||
"cwd": "${workspaceRoot}", | ||
"protocol": "inspector", | ||
} | ||
] | ||
} |
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 |
---|---|---|
@@ -0,0 +1,23 @@ | ||
FROM node:10-alpine | ||
|
||
WORKDIR /usr/src/app | ||
|
||
RUN apk update && \ | ||
apk upgrade && \ | ||
apk add --no-cache --virtual install \ | ||
python \ | ||
make \ | ||
g++ \ | ||
git | ||
|
||
COPY package*.json ./ | ||
|
||
RUN npm install --unsafe-perm && \ | ||
apk del install | ||
|
||
COPY . . | ||
|
||
RUN npm run build && \ | ||
npm prune --production | ||
|
||
CMD ["node", "./out/app.js"] |
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 |
---|---|---|
@@ -0,0 +1,18 @@ | ||
##### Build | ||
``` | ||
docker build . -t dschu012/d2s:latest | ||
``` | ||
|
||
Run | ||
``` | ||
docker run dschu012/d2s:latest \ | ||
-p 8080:3030 \ | ||
-e EXTENDED_STASH=true | ||
-v /path/to/saves:/data/saves:ro \ | ||
-v /path/to/txt:/data/txt:ro \ | ||
-v /path/to/img:/data/img:ro \ | ||
``` | ||
|
||
##### Examples | ||
* https://diablo.dannyschumacher.com/#/ | ||
* https://resurgence.dannyschumacher.com/#/ |
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 |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import express from "express"; | ||
import d2s from "./v1/d2s.routes"; | ||
import img from "./v1/img.routes"; | ||
import config from "./v1/config.routes"; | ||
|
||
let router: express.Router = express.Router(); | ||
|
||
router.use("/v1/d2s", d2s); | ||
router.use("/v1/img", img); | ||
router.use("/v1/config", config); | ||
|
||
|
||
export default router; |
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 |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import express from "express"; | ||
import dotenv from "dotenv"; | ||
|
||
dotenv.config(); | ||
|
||
let router: express.Router = express.Router(); | ||
|
||
router.get("/", async (req, res) => { | ||
res.json({ | ||
VUE_APP_INV_WIDTH: process.env.VUE_APP_INV_WIDTH || 10, | ||
VUE_APP_INV_HEIGHT: process.env.VUE_APP_INV_HEIGHT || 4, | ||
VUE_APP_STASH_WIDTH: process.env.VUE_APP_STASH_WIDTH || 6, | ||
VUE_APP_STASH_HEIGHT: process.env.VUE_APP_STASH_HEIGHT || 8, | ||
VUE_APP_CUBE_WIDTH: process.env.VUE_APP_CUBE_WIDTH || 3, | ||
VUE_APP_CUBE_HEIGHT: process.env.VUE_APP_CUBE_HEIGHT || 4, | ||
}); | ||
}); | ||
|
||
export default router; |
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 |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import express from "express"; | ||
import path from "path"; | ||
import fs from "fs"; | ||
import { read, readConstantData, types } from "d2s"; | ||
import dotenv from "dotenv"; | ||
import glob from "glob"; | ||
|
||
dotenv.config(); | ||
|
||
let router: express.Router = express.Router(); | ||
let c: types.IConstantData; | ||
|
||
/* | ||
* Load up constant data when start server | ||
*/ | ||
(async () => { | ||
let base = process.env.MPQ_DATA_DIR as string; | ||
let files = {} as any; | ||
let dir = path.join(`${base}/global/excel/`); | ||
try { | ||
fs.readdirSync(dir).forEach(file => { | ||
if (file.endsWith(".txt")) { | ||
files[file] = fs.readFileSync(path.join(dir, file), 'utf8'); | ||
} | ||
}); | ||
dir = path.join(`${base}/local/LNG/ENG/`); | ||
fs.readdirSync(dir).forEach(file => { | ||
if (file.endsWith(".txt")) { | ||
files[file] = fs.readFileSync(path.join(dir, file), 'utf8'); | ||
} | ||
}); | ||
c = await readConstantData(files); | ||
} catch (e) { | ||
console.error(e); | ||
process.exit(1); | ||
} | ||
})(); | ||
|
||
router.get("/character/:character", async (req, res) => { | ||
try { | ||
const base = process.env.SAVE_DIR as string; | ||
const files = await glob.sync(path.join(base, `**/${req.params.character}?(.d2s)`), { nodir: true, nocase: true }); | ||
if(!files.length) { | ||
throw new Error(`${req.params.character} save not found.`); | ||
} | ||
const buffer = fs.readFileSync(files[0]); | ||
const s = await read(buffer, c, { extendedStash: process.env.EXTENDED_STASH == "true"}); | ||
res.json(s); | ||
} catch (e) { | ||
console.log(e); | ||
} | ||
}); | ||
|
||
router.get("/list", async (req, res) => { | ||
const base = process.env.SAVE_DIR as string; | ||
const files = await glob.sync(path.join(base, `**`), { nodir: true }).map(file => path.basename(file, '.d2s')); | ||
res.json(files); | ||
}); | ||
|
||
export default router; |
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 |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import express from "express"; | ||
import path from "path"; | ||
import fs from "fs"; | ||
import dotenv from "dotenv"; | ||
import jimp from "jimp"; | ||
import glob from "glob"; | ||
|
||
dotenv.config(); | ||
|
||
let router: express.Router = express.Router(); | ||
|
||
const palette = [] as any; | ||
const mappings = [] as any; | ||
|
||
const colormaps = { | ||
1: '/global/items/Palette/grey.dat', | ||
2: '/global/items/Palette/grey2.dat', | ||
5: '/global/items/Palette/greybrown.dat', | ||
6: '/global/items/Palette/invgrey.dat', | ||
7: '/global/items/Palette/invgrey2.dat', | ||
8: '/global/items/Palette/invgreybrown.dat', | ||
}; | ||
|
||
const colors = { | ||
whit: 0, | ||
lgry: 1, | ||
dgry: 2, | ||
blac: 3, | ||
lblu: 4, | ||
dblu: 5, | ||
cblu: 6, | ||
lred: 7, | ||
dred: 8, | ||
cred: 9, | ||
lgrn: 10, | ||
dgrn: 11, | ||
cgrn: 12, | ||
lyel: 13, | ||
dyel: 14, | ||
lgld: 15, | ||
dgld: 16, | ||
lpur: 17, | ||
dpur: 18, | ||
oran: 19, | ||
bwht: 20, | ||
}; | ||
|
||
|
||
const base = process.env.IMG_DATA_DIR as string || process.env.MPQ_DATA_DIR as string; | ||
/* | ||
* Load up constant data when start server | ||
*/ | ||
(async () => { | ||
|
||
async function loadPalette(f: string) { | ||
const buffer = fs.readFileSync(path.join(base, f)); | ||
for (let i = 0; i < 256; i += 1) { | ||
palette.push([buffer[i * 3 + 2], buffer[i * 3 + 1], buffer[i * 3]]); | ||
} | ||
}; | ||
async function loadMapping(key: any, f: string) { | ||
const buffer = fs.readFileSync(path.join(base, f)); | ||
const mapping = []; | ||
for (let i = 0; i < Object.keys(colors).length; i += 1) { | ||
mapping.push(buffer.slice(0 + (i * 256), 256 + (i * 256))); | ||
} | ||
mappings[key] = mapping; | ||
}; | ||
|
||
try { | ||
loadPalette(`/global/palette/ACT1/pal.dat`); | ||
for(const key in colormaps) { | ||
loadMapping(key, colormaps[key]); | ||
} | ||
} catch(e) { | ||
console.log(e); | ||
process.exit(1); | ||
} | ||
})(); | ||
|
||
|
||
router.get("/:file.png", async (req, res) => { | ||
try { | ||
//we only care about first frame | ||
const files = await glob.sync(path.join(base, '/global/items', `${req.params.file}.dc6`), { nodir: true, nocase: true }); | ||
if(files.length === 0) { | ||
throw new Error(`File not found ${req.params.file}.dc6`); | ||
} | ||
const dc6 = fs.readFileSync(files[0]); | ||
const width = dc6.readUInt32LE(32); | ||
const height = dc6.readUInt32LE(36); | ||
const length = dc6.readUInt32LE(56); | ||
let x = 0, y = height - 1; | ||
const indexed = [] as any; | ||
for (let i = 0; i < height; i += 1) { | ||
indexed[i] = Array(width).fill(255); | ||
} | ||
for (let i = 0; i < length;) { | ||
let b = dc6.readUInt8(60 + i++); | ||
if (b === 0x80) { //eol | ||
x = 0, y--; | ||
} else if (b & 0x80) { | ||
x += b & 0x7F; //transparent repeat for N bytes | ||
} else { | ||
//read N bytes | ||
for(let j = 0; j < b; j++) { | ||
indexed[y][x++] = dc6.readUInt8(60 + i++); | ||
} | ||
} | ||
} | ||
new jimp(width, height, async function (err, image) { | ||
let data = image.bitmap.data; | ||
for (let y = 0; y < height; y += 1) { | ||
for (let x = 0; x < width; x += 1) { | ||
let paletteIdx = indexed[y][x]; | ||
const offset = (y * width + x) * 4; | ||
if(paletteIdx === 255) { //transparent | ||
continue; | ||
} | ||
if(req.query.inv_transform && req.query.transform_color) { | ||
let transformIdx = colors[req.query.transform_color]; | ||
if(transformIdx >= 0 && mappings[req.query.inv_transform]) { | ||
paletteIdx = mappings[req.query.inv_transform][transformIdx][paletteIdx]; | ||
} | ||
} | ||
const rgb = palette[paletteIdx]; | ||
data[offset] = rgb[0]; | ||
data[offset + 1] = rgb[1]; | ||
data[offset + 2] = rgb[2]; | ||
data[offset + 3] = 255; | ||
} | ||
} | ||
let buffer = await image.getBufferAsync(jimp.MIME_PNG); | ||
res.writeHead(200, { | ||
'Content-Type': 'image/png', | ||
'Cache-Control': 'public, max-age=31557600, s-maxage=31557600' | ||
}); | ||
res.end(buffer, 'binary'); | ||
}) | ||
} catch (e) { | ||
console.log(e); | ||
res.writeHead(404); | ||
res.end(); | ||
} | ||
}); | ||
|
||
export default router; |
Oops, something went wrong.