Created
August 10, 2022 16:00
-
-
Save barncastle/addb4287d9e8a6b50e5ba48c0ab931dc to your computer and use it in GitHub Desktop.
Core functions for reading War For Kingship's BIN files
This file contains hidden or 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
var PackageItemType; | |
(function (PackageItemType) { | |
PackageItemType[PackageItemType["Image"] = 0] = "Image"; | |
PackageItemType[PackageItemType["MovieClip"] = 1] = "MovieClip"; | |
PackageItemType[PackageItemType["Sound"] = 2] = "Sound"; | |
PackageItemType[PackageItemType["Component"] = 3] = "Component"; | |
PackageItemType[PackageItemType["Atlas"] = 4] = "Atlas"; | |
PackageItemType[PackageItemType["Font"] = 5] = "Font"; | |
PackageItemType[PackageItemType["Swf"] = 6] = "Swf"; | |
PackageItemType[PackageItemType["Misc"] = 7] = "Misc"; | |
PackageItemType[PackageItemType["Unknown"] = 8] = "Unknown"; | |
})(PackageItemType = {}); | |
var ObjectType; | |
(function (ObjectType) { | |
ObjectType[ObjectType["Image"] = 0] = "Image"; | |
ObjectType[ObjectType["MovieClip"] = 1] = "MovieClip"; | |
ObjectType[ObjectType["Swf"] = 2] = "Swf"; | |
ObjectType[ObjectType["Graph"] = 3] = "Graph"; | |
ObjectType[ObjectType["Loader"] = 4] = "Loader"; | |
ObjectType[ObjectType["Group"] = 5] = "Group"; | |
ObjectType[ObjectType["Text"] = 6] = "Text"; | |
ObjectType[ObjectType["RichText"] = 7] = "RichText"; | |
ObjectType[ObjectType["InputText"] = 8] = "InputText"; | |
ObjectType[ObjectType["Component"] = 9] = "Component"; | |
ObjectType[ObjectType["List"] = 10] = "List"; | |
ObjectType[ObjectType["Label"] = 11] = "Label"; | |
ObjectType[ObjectType["Button"] = 12] = "Button"; | |
ObjectType[ObjectType["ComboBox"] = 13] = "ComboBox"; | |
ObjectType[ObjectType["ProgressBar"] = 14] = "ProgressBar"; | |
ObjectType[ObjectType["Slider"] = 15] = "Slider"; | |
ObjectType[ObjectType["ScrollBar"] = 16] = "ScrollBar"; | |
ObjectType[ObjectType["Tree"] = 17] = "Tree"; | |
})(ObjectType = {}); | |
class UIPackage { | |
constructor() { | |
this.id = null; | |
this.name = null; | |
this._resKey = null; // internal name e.g. FightView | |
this._items = new Array(); | |
this._itemsById = {}; | |
this._itemsByName = {}; | |
this._sprites = {}; | |
this._dependencies = new Array(); | |
this._branches = new Array(); | |
this._branchIndex = -1; | |
} | |
} | |
class PackageItem { | |
constructor(_owner) { | |
this.owner = _owner; | |
this.type = null; | |
this.id = null; | |
this.name = null; | |
this.file = null; | |
this.objectType = -1; | |
this.width = 0; | |
this.height = 0; | |
this.tileGridIndice = 0; | |
this.interval = 0; | |
this.repeatDelay = 0; | |
this.scaleByTile = false; | |
this.smoothing = false; | |
this.rawData = null; | |
this.pixelHitTestData = null; // PixelHitTestData | |
this.scale9Grid = null; // Rectangle | |
} | |
} | |
class PixelHitTestData { | |
constructor() { | |
this.pixelWidth = 0; | |
this.scale = 1; | |
this.pixels = []; | |
} | |
} | |
class AtlasSprite() { | |
constructor() { | |
this.rect = new Rectangle(); | |
this.offset = new Point(); | |
this.originalSize = new Point(); | |
this.atlas = null; // PackageItem | |
this.rotated = false; | |
} | |
} | |
class Rectangle { | |
constructor() { | |
this.x = 0; | |
this.y = 0; | |
this.width = 0; | |
this.height = 0; | |
} | |
} | |
class Point { | |
constructor() { | |
this.x = 0; | |
this.y = 0; | |
} | |
} | |
UIPackage.prototype.loadPackage = function (buffer) { | |
if (buffer.readUnsignedInt() != 0x46475549) | |
throw "FairyGUI: old package format found"; | |
// read header | |
buffer.version = buffer.readInt(); | |
var compressed = buffer.readBool(); | |
this._id = buffer.readUTF(); | |
this._name = buffer.readUTF(); | |
buffer.position += 20; // skip | |
// zlib decompress if required | |
if (compressed) { | |
var buf = new Uint8Array(buffer.buffer, buffer.position, buffer.length - buffer.position); | |
var inflater = new Zlib.RawInflate(buf); | |
var buffer2 = new ByteBuffer(inflater.decompress()); | |
buffer2.version = buffer.version; | |
buffer = buffer2; | |
} | |
var cnt, i; | |
var fileNamePrefix = this._resKey + "_"; | |
// the index table is a byte count, bool useShort and ushort/uint array struct | |
// each value is an offset to a specific block of data or 0 if unused | |
// -- see ByteBuffer.seek -- | |
var indexTablePos = buffer.position; | |
// block 4 - string table | |
buffer.seek(indexTablePos, 4); | |
cnt = buffer.readInt(); | |
buffer.stringTable = new Array(cnt); | |
for (i = 0; i < cnt; i++) | |
buffer.stringTable[i] = buffer.readUTF(); | |
// block 0 - dependancies and branches | |
buffer.seek(indexTablePos, 0); | |
cnt = buffer.readShort(); | |
for (i = 0; i < cnt; i++) | |
this._dependencies.push({ id: buffer.readS(), name: buffer.readS() }); | |
if (buffer.version >= 2) { | |
cnt = buffer.readShort(); | |
this._branches = buffer.readSArray(cnt); | |
} | |
// block 1 - PackageItems | |
buffer.seek(indexTablePos, 1); | |
cnt = buffer.readShort(); | |
for (i = 0; i < cnt; i++) { | |
var nextPos = buffer.readInt() + buffer.position; | |
var pi = new PackageItem(this); | |
pi.type = buffer.readByte(); | |
pi.id = buffer.readS(); | |
pi.name = buffer.readS(); | |
buffer.readS(); // deprecated | |
pi.file = buffer.readS(); | |
buffer.readBool(); // deprecated | |
pi.width = buffer.readInt(); | |
pi.height = buffer.readInt(); | |
switch (pi.type) { | |
case PackageItemType.Image: | |
{ | |
pi.objectType = ObjectType.Image; | |
var scaleOption = buffer.readByte(); | |
if (scaleOption == 1) { | |
pi.scale9Grid = new Rectangle(); | |
pi.scale9Grid.x = buffer.readInt(); | |
pi.scale9Grid.y = buffer.readInt(); | |
pi.scale9Grid.width = buffer.readInt(); | |
pi.scale9Grid.height = buffer.readInt(); | |
pi.tileGridIndice = buffer.readInt(); | |
} | |
else if (scaleOption == 2) { | |
pi.scaleByTile = true; | |
} | |
pi.smoothing = buffer.readBool(); | |
break; | |
} | |
case PackageItemType.MovieClip: | |
{ | |
pi.objectType = ObjectType.MovieClip; | |
pi.smoothing = buffer.readBool(); | |
pi.rawData = buffer.readBuffer(); | |
break; | |
} | |
case PackageItemType.Font: | |
{ | |
pi.rawData = buffer.readBuffer(); | |
break; | |
} | |
case PackageItemType.Component: | |
{ | |
var extension = buffer.readByte(); | |
pi.objectType = extension || ObjectType.Component; | |
pi.rawData = buffer.readBuffer(); | |
break; | |
} | |
case PackageItemType.Atlas: | |
case PackageItemType.Sound: | |
case PackageItemType.Misc: | |
{ | |
pi.file = fileNamePrefix + getFileName(pi.file); | |
break; | |
} | |
} | |
if (buffer.version >= 2) { | |
var str = buffer.readS(); | |
if (str) | |
pi.name = str + "/" + pi.name; | |
var branchCnt = buffer.readUnsignedByte(); | |
if (branchCnt > 0) { | |
if (this._branches.Length > 0) | |
pi.branches = buffer.readSArray(branchCnt); | |
else | |
this._itemsById[buffer.readS()] = pi; | |
} | |
var highResCnt = buffer.readUnsignedByte(); | |
pi.highResolution = buffer.readSArray(highResCnt); | |
} | |
this._items.push(pi); | |
this._itemsById[pi.id] = pi; | |
if (pi.name != null) | |
this._itemsByName[pi.name] = pi; | |
buffer.position = nextPos; | |
} | |
// block 2 - sprites | |
buffer.seek(indexTablePos, 2); | |
cnt = buffer.readShort(); | |
for (i = 0; i < cnt; i++) { | |
var nextPos = buffer.readShort() + buffer.position; | |
var itemId = buffer.readS(); | |
var sprite = new AtlasSprite(); | |
sprite.atlas = this._itemsById[buffer.readS()]; | |
sprite.rect.x = buffer.readInt(); | |
sprite.rect.y = buffer.readInt(); | |
sprite.rect.width = buffer.readInt(); | |
sprite.rect.height = buffer.readInt(); | |
sprite.rotated = buffer.readBool(); | |
if (buffer.version >= 2 && buffer.readBool()) { | |
sprite.offset.x = buffer.readInt(); | |
sprite.offset.y = buffer.readInt(); | |
sprite.originalSize.x = buffer.readInt(); | |
sprite.originalSize.y = buffer.readInt(); | |
} | |
else { | |
sprite.originalSize.x = sprite.rect.width; | |
sprite.originalSize.y = sprite.rect.height; | |
} | |
this._sprites[itemId] = sprite; | |
buffer.position = nextPos; | |
} | |
// block 3 (optional) - HitTestData for Image items | |
if (buffer.seek(indexTablePos, 3)) { | |
cnt = buffer.readShort(); | |
for (i = 0; i < cnt; i++) { | |
var nextPos = buffer.readInt() + buffer.position; | |
var pi = this._itemsById[buffer.readS()]; | |
if (pi && pi.type == PackageItemType.Image) { | |
pi.pixelHitTestData = new PixelHitTestData(); | |
pi.pixelHitTestData.load(buffer); | |
} | |
buffer.position = nextPos; | |
} | |
} | |
}; | |
PixelHitTestData.prototype.load = function (buffer) { | |
buffer.readInt(); // deprecated | |
this.pixelWidth = buffer.readInt(); | |
this.scale = 1 / buffer.readByte(); | |
this.pixels = []; | |
var len = buffer.readInt(); | |
for (var i = 0; i < len; i++) { | |
this.pixels[i] = buffer.readByte() & 0xFF; // unsigned cast | |
} | |
}; | |
function getFileName(source) { | |
var i = source.lastIndexOf("/"); | |
if (i != -1) | |
source = source.substr(i + 1); | |
i = source.lastIndexOf("\\"); | |
if (i != -1) | |
source = source.substr(i + 1); | |
i = source.lastIndexOf("."); | |
if (i != -1) | |
return source.substring(0, i); | |
return source; | |
}; | |
class ByteBuffer extends egret.ByteArray { | |
constructor(buffer, bufferExtSize) { | |
super(this, buffer, bufferExtSize); | |
this.stringTable = null; | |
this.version = 0; | |
} | |
readBool() { | |
return this.readByte() == 1; | |
} | |
readS() { | |
var index = this.readUnsignedShort(); | |
if (index == 0xFFFE) | |
return null; | |
if (index == 0xFFFD) | |
return ""; | |
return this.stringTable[index]; | |
} | |
readSArray(cnt) { | |
var ret = new Array(cnt); | |
for (var i = 0; i < cnt; i++) | |
ret[i] = this.readS(); | |
return ret; | |
} | |
readBuffer() { | |
var count = this.readUnsignedInt(); // new buffer byte size | |
var ba = new ByteBuffer(new Uint8Array(this.buffer, this.position, count)); | |
ba.stringTable = this.stringTable; | |
ba.version = this.version; | |
this.position += count; | |
return ba; | |
} | |
seek(indexTablePos, blockIndex) { | |
var tmp = this.position; | |
this.position = indexTablePos; | |
var segCount = this.readByte(); | |
var useShort = this.readBool(); | |
var newPos = 0; | |
if (blockIndex < segCount) { | |
if (useShort) { | |
this.position += 2 * blockIndex; | |
newPos = this.readUnsignedShort(); | |
} | |
else { | |
this.position += 4 * blockIndex; | |
newPos = this.readUnsignedInt(); | |
} | |
} | |
if (newPos > 0) { | |
this.position = indexTablePos + newPos; | |
return true; | |
} else { | |
this.position = tmp; | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment