public void decode(Default317Buffer stream, Envelope envelope) { int count = stream.getUnsignedByte(); pairCount[0] = count >> 4; pairCount[1] = count & 0xf; if (count != 0) { unity[0] = stream.getUnsignedLEShort(); unity[1] = stream.getUnsignedLEShort(); int migrated = stream.getUnsignedByte(); for (int direction = 0; direction < 2; direction++) { for (int pair = 0; pair < pairCount[direction]; pair++) { pairPhase[direction, 0, pair] = stream.getUnsignedLEShort(); pairMagnitude[direction, 0, pair] = stream.getUnsignedLEShort(); } } for (int direction = 0; direction < 2; direction++) { for (int pair = 0; pair < pairCount[direction]; pair++) { if ((migrated & 1 << direction * 4 << pair) != 0) { pairPhase[direction, 1, pair] = stream.getUnsignedLEShort(); pairMagnitude[direction, 1, pair] = stream.getUnsignedLEShort(); } else { pairPhase[direction, 1, pair] = pairPhase[direction, 0, pair]; pairMagnitude[direction, 1, pair] = pairMagnitude[direction, 0, pair]; } } } if (migrated != 0 || unity[1] != unity[0]) { envelope.decodeShape(stream); } } else { unity[0] = unity[1] = 0; } }
public static void load(Archive streamLoader) { Default317Buffer stream = new Default317Buffer(streamLoader.decompressFile("idk.dat")); count = stream.getUnsignedLEShort(); if (cache == null) { cache = new IdentityKit[count]; } for (int kit = 0; kit < count; kit++) { if (cache[kit] == null) { cache[kit] = new IdentityKit(); } cache[kit].loadDefinition(stream); } }
public static void load(Archive archive) { Default317Buffer stream = new Default317Buffer(archive.decompressFile("flo.dat")); int cacheSize = stream.getUnsignedLEShort(); if (cache == null) { cache = new FloorDefinition[cacheSize]; } for (int j = 0; j < cacheSize; j++) { if (cache[j] == null) { cache[j] = new FloorDefinition(); } cache[j].loadDefinition(stream); } }
public static void unpackConfig(Archive streamLoader) { Default317Buffer stream = new Default317Buffer(streamLoader.decompressFile("seq.dat")); int length = stream.getUnsignedLEShort(); if (animations == null) { animations = new AnimationSequence[length]; } for (int animation = 0; animation < length; animation++) { if (animations[animation] == null) { animations[animation] = new AnimationSequence(); } animations[animation].readValues(stream); } }
private void loadDefinition(Default317Buffer stream) { do { int opcode = stream.getUnsignedByte(); if (opcode == 0) { return; } if (opcode == 1) { partId = stream.getUnsignedByte(); } else if (opcode == 2) { int modelCount = stream.getUnsignedByte(); modelIds = new int[modelCount]; for (int m = 0; m < modelCount; m++) { modelIds[m] = stream.getUnsignedLEShort(); } } else if (opcode == 3) { widgetDisplayed = true; } else if (opcode >= 40 && opcode < 50) { originalModelColours[opcode - 40] = stream.getUnsignedLEShort(); } else if (opcode >= 50 && opcode < 60) { modifiedModelColours[opcode - 50] = stream.getUnsignedLEShort(); } else if (opcode >= 60 && opcode < 70) { headModelIds[opcode - 60] = stream.getUnsignedLEShort(); } else { Console.WriteLine($"Error unrecognized config code: {opcode}"); } } while(true); }
public static void load(Archive archive) { Default317Buffer buffer = new Default317Buffer(archive.decompressFile("spotanim.dat")); int count = buffer.getUnsignedLEShort(); if (cache == null) { cache = new SpotAnimation[count]; } for (int anim = 0; anim < count; anim++) { if (cache[anim] == null) { cache[anim] = new SpotAnimation(); } cache[anim].id = anim; cache[anim].read(buffer); } }
public static void load(Archive streamLoader) { EntityDefinition.stream = new Default317Buffer(streamLoader.decompressFile("npc.dat")); Default317Buffer stream = new Default317Buffer(streamLoader.decompressFile("npc.idx")); int size = stream.getUnsignedLEShort(); EntityDefinition.streamOffsets = new int[size]; int offset = 2; for (int n = 0; n < size; n++) { EntityDefinition.streamOffsets[n] = offset; offset += stream.getUnsignedLEShort(); } EntityDefinition.cache = new EntityDefinition[20]; for (int c = 0; c < 20; c++) { EntityDefinition.cache[c] = new EntityDefinition(); } }
public static void load(Archive streamLoader) { stream = new Default317Buffer(streamLoader.decompressFile("obj.dat")); Default317Buffer index = new Default317Buffer(streamLoader.decompressFile("obj.idx")); itemCount = index.getUnsignedLEShort(); streamOffsets = new int[itemCount]; int offset = 2; for (int item = 0; item < itemCount; item++) { streamOffsets[item] = offset; offset += index.getUnsignedLEShort(); } cache = new ItemDefinition[10]; for (int definition = 0; definition < 10; definition++) { cache[definition] = new ItemDefinition(); } }
public static void load(Archive archive) { GameObjectDefinition.stream = new Default317Buffer(archive.decompressFile("loc.dat")); Default317Buffer indexStream = new Default317Buffer(archive.decompressFile("loc.idx")); int objectCount = indexStream.getUnsignedLEShort(); streamOffsets = new int[objectCount]; int offset = 2; for (int index = 0; index < objectCount; index++) { streamOffsets[index] = offset; offset += indexStream.getUnsignedLEShort(); } cache = new GameObjectDefinition[20]; for (int c = 0; c < 20; c++) { cache[c] = new GameObjectDefinition(); } }
public Archive(byte[] data) { Default317Buffer buffer = new Default317Buffer(data); int compressedLength = buffer.get3Bytes(); int decompressedLength = buffer.get3Bytes(); if (decompressedLength != compressedLength) { byte[] output = new byte[compressedLength]; Bzip2Decompressor.decompress(output, compressedLength, data, decompressedLength, 6); outputData = output; buffer = new Default317Buffer(outputData); this.decompressed = true; } else { outputData = data; this.decompressed = false; } fileCount = buffer.getUnsignedLEShort(); hashes = new int[fileCount]; decompressedSizes = new int[fileCount]; compressedSizes = new int[fileCount]; initialOffsets = new int[fileCount]; int offset = buffer.position + fileCount * 10; for (int index = 0; index < fileCount; index++) { hashes[index] = buffer.getInt(); decompressedSizes[index] = buffer.get3Bytes(); compressedSizes[index] = buffer.get3Bytes(); initialOffsets[index] = offset; offset += compressedSizes[index]; } }
private void load(Default317Buffer buffer) { do { int opcode = buffer.getUnsignedByte(); if (opcode == 0) { return; } if (opcode == 1) { configId = buffer.getUnsignedLEShort(); leastSignificantBit = buffer.getUnsignedByte(); mostSignificantBit = buffer.getUnsignedByte(); } else if (opcode == 10) { buffer.getString(); } else if (opcode == 2) { } // dummy else if (opcode == 3) { buffer.getInt(); } else if (opcode == 4) { buffer.getInt(); } else { throw new InvalidOperationException($"Error unrecognised config code: {opcode}"); } } while(true); }
public IReadOnlyList <MapObject> Deserialize() { List <MapObject> mapObjects = new List <MapObject>(20); //Following code is from Region.loadObjectBlock Default317Buffer stream = MapObjectListBuffer; int objectId = -1; do { int objectIdOffset = stream.getSmartB(); if (objectIdOffset == 0) { break; } objectId += objectIdOffset; int position = 0; do { int positionOffset = stream.getSmartB(); if (positionOffset == 0) { break; } position += positionOffset - 1; int hash = stream.getUnsignedByte(); int type = hash >> 2; int orientation = hash & 3; mapObjects.Add(new MapObject(objectId, position, type, orientation)); } while(true); } while(true); return(mapObjects); }
public IndexedImage(Archive archive, String name, int id) { try { Default317Buffer imageBuffer = new Default317Buffer(archive.decompressFile(name + ".dat")); Default317Buffer metadataBuffer = new Default317Buffer(archive.decompressFile("index.dat")); metadataBuffer.position = imageBuffer.getUnsignedLEShort(); resizeWidth = metadataBuffer.getUnsignedLEShort(); resizeHeight = metadataBuffer.getUnsignedLEShort(); int colourCount = metadataBuffer.getUnsignedByte(); palette = new int[colourCount]; for (int c = 0; c < colourCount - 1; c++) { palette[c + 1] = metadataBuffer.get3Bytes(); } for (int i = 0; i < id; i++) { metadataBuffer.position += 2; imageBuffer.position += metadataBuffer.getUnsignedLEShort() * metadataBuffer.getUnsignedLEShort(); metadataBuffer.position++; } drawOffsetX = metadataBuffer.getUnsignedByte(); drawOffsetY = metadataBuffer.getUnsignedByte(); width = metadataBuffer.getUnsignedLEShort(); height = metadataBuffer.getUnsignedLEShort(); int type = metadataBuffer.getUnsignedByte(); int pixelCount = width * height; pixels = new byte[pixelCount]; if (type == 0) { for (int i = 0; i < pixelCount; i++) { pixels[i] = imageBuffer.get(); } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { pixels[x + y * width] = imageBuffer.get(); } } } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate IndexedImage for: {name} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
public Sprite(Archive streamLoader, String target, int archiveId) { try { if (target.ToLower() == "headicons") { return; } Default317Buffer dataStream = new Default317Buffer(streamLoader.decompressFile(target + ".dat")); Default317Buffer indexStream = new Default317Buffer(streamLoader.decompressFile("index.dat")); indexStream.position = dataStream.getUnsignedLEShort(); maxWidth = indexStream.getUnsignedLEShort(); maxHeight = indexStream.getUnsignedLEShort(); int length = indexStream.getUnsignedByte(); int[] pixels = new int[length]; for (int p = 0; p < length - 1; p++) { pixels[p + 1] = indexStream.get3Bytes(); if (pixels[p + 1] == 0) { pixels[p + 1] = 1; } } for (int i = 0; i < archiveId; i++) { indexStream.position += 2; dataStream.position += indexStream.getUnsignedLEShort() * indexStream.getUnsignedLEShort(); indexStream.position++; } offsetX = indexStream.getUnsignedByte(); offsetY = indexStream.getUnsignedByte(); width = indexStream.getUnsignedLEShort(); height = indexStream.getUnsignedLEShort(); int type = indexStream.getUnsignedByte(); int pixelCount = width * height; this.pixels = new int[pixelCount]; if (type == 0) { for (int p = 0; p < pixelCount; p++) { this.pixels[p] = pixels[dataStream.getUnsignedByte()]; } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { this.pixels[x + y * width] = pixels[dataStream.getUnsignedByte()]; } } } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate Sprite for: {target} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
internal async Task LoadMediaContentAsync() { Archive archiveMedia = requestArchive(4, "2d graphics", "media", 0, 40); Default317Buffer metadataBuffer = new Default317Buffer(archiveMedia.decompressFile("index.dat")); inventoryBackgroundImage = new IndexedImage(archiveMedia, "invback", 0, metadataBuffer); chatBackgroundImage = new IndexedImage(archiveMedia, "chatback", 0, metadataBuffer); minimapBackgroundImage = new IndexedImage(archiveMedia, "mapback", 0, metadataBuffer); backBase1Image = new IndexedImage(archiveMedia, "backbase1", 0, metadataBuffer); backBase2Image = new IndexedImage(archiveMedia, "backbase2", 0, metadataBuffer); backHmid1Image = new IndexedImage(archiveMedia, "backhmid1", 0, metadataBuffer); for (int icon = 0; icon < 13; icon++) { sideIconImage[icon] = new IndexedImage(archiveMedia, "sideicons", icon, metadataBuffer); } minimapCompassImage = new Sprite(archiveMedia, "compass", 0, metadataBuffer); minimapEdgeImage = new Sprite(archiveMedia, "mapedge", 0, metadataBuffer); minimapEdgeImage.trim(); await TaskDelayFactory.Create(1); try { for (int i = 0; i < 100; i++) { mapSceneImage[i] = new IndexedImage(archiveMedia, "mapscene", i, metadataBuffer); } await TaskDelayFactory.Create(1); } catch (Exception _ex) { signlink.reporterror($"Unexpected Exception: {_ex.Message} \n\n Stack: {_ex.StackTrace}"); } try { for (int i = 0; i < 100; i++) { mapFunctionImage[i] = new Sprite(archiveMedia, "mapfunction", i, metadataBuffer); } await TaskDelayFactory.Create(1); } catch (Exception _ex) { signlink.reporterror($"Unexpected Exception: {_ex.Message} \n\n Stack: {_ex.StackTrace}"); } try { for (int i = 0; i < 20; i++) { hitMarkImage[i] = new Sprite(archiveMedia, "hitmarks", i, metadataBuffer); } await TaskDelayFactory.Create(1); } catch (Exception _ex) { signlink.reporterror($"Unexpected Exception: {_ex.Message} \n\n Stack: {_ex.StackTrace}"); } try { for (int i = 0; i < 20; i++) { headIcons[i] = new Sprite(archiveMedia, "headicons", i, metadataBuffer); } await TaskDelayFactory.Create(1); } catch (Exception _ex) { signlink.reporterror($"Unexpected Exception: {_ex.Message} \n\n Stack: {_ex.StackTrace}"); throw; } mapFlag = new Sprite(archiveMedia, "mapmarker", 0, metadataBuffer); mapMarker = new Sprite(archiveMedia, "mapmarker", 1, metadataBuffer); for (int i = 0; i < 8; i++) { crosses[i] = new Sprite(archiveMedia, "cross", i, metadataBuffer); } mapDotItem = new Sprite(archiveMedia, "mapdots", 0, metadataBuffer); mapDotNPC = new Sprite(archiveMedia, "mapdots", 1, metadataBuffer); mapDotPlayer = new Sprite(archiveMedia, "mapdots", 2, metadataBuffer); mapDotFriend = new Sprite(archiveMedia, "mapdots", 3, metadataBuffer); mapDotTeam = new Sprite(archiveMedia, "mapdots", 4, metadataBuffer); scrollBarUp = new IndexedImage(archiveMedia, "scrollbar", 0, metadataBuffer); scrollBarDown = new IndexedImage(archiveMedia, "scrollbar", 1, metadataBuffer); redStone1 = new IndexedImage(archiveMedia, "redstone1", 0, metadataBuffer); redStone2 = new IndexedImage(archiveMedia, "redstone2", 0, metadataBuffer); redStone3 = new IndexedImage(archiveMedia, "redstone3", 0, metadataBuffer); redStone1_2 = new IndexedImage(archiveMedia, "redstone1", 0, metadataBuffer); redStone1_2.flipHorizontally(); redStone2_2 = new IndexedImage(archiveMedia, "redstone2", 0, metadataBuffer); redStone2_2.flipHorizontally(); redStone1_3 = new IndexedImage(archiveMedia, "redstone1", 0, metadataBuffer); redStone1_3.flipVertically(); redStone2_3 = new IndexedImage(archiveMedia, "redstone2", 0, metadataBuffer); redStone2_3.flipVertically(); redStone3_2 = new IndexedImage(archiveMedia, "redstone3", 0, metadataBuffer); redStone3_2.flipVertically(); redStone1_4 = new IndexedImage(archiveMedia, "redstone1", 0, metadataBuffer); redStone1_4.flipHorizontally(); redStone1_4.flipVertically(); redStone2_4 = new IndexedImage(archiveMedia, "redstone2", 0, metadataBuffer); redStone2_4.flipHorizontally(); redStone2_4.flipVertically(); for (int i = 0; i < 2; i++) { modIcons[i] = new IndexedImage(archiveMedia, "mod_icons", i, metadataBuffer); } await TaskDelayFactory.Create(1); Sprite sprite = new Sprite(archiveMedia, "backleft1", 0, metadataBuffer); backLeftIP1 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backLeftIP1)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backleft2", 0, metadataBuffer); backLeftIP2 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backLeftIP2)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backright1", 0, metadataBuffer); backRightIP1 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backRightIP1)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backright2", 0, metadataBuffer); backRightIP2 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backRightIP2)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backtop1", 0, metadataBuffer); backTopIP1 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backTopIP1)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backvmid1", 0, metadataBuffer); backVmidIP1 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backVmidIP1)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backvmid2", 0, metadataBuffer); backVmidIP2 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backVmidIP2)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backvmid3", 0, metadataBuffer); backVmidIP3 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backVmidIP3)); sprite.drawInverse(0, 0); sprite = new Sprite(archiveMedia, "backhmid2", 0, metadataBuffer); backVmidIP2_2 = CreateNewImageProducer(sprite.width, sprite.height, nameof(backVmidIP2_2)); sprite.drawInverse(0, 0); await TaskDelayFactory.Create(1); int randomRed = (int)(StaticRandomGenerator.Next() * 21D) - 10; int randomGreen = (int)(StaticRandomGenerator.Next() * 21D) - 10; int randomBlue = (int)(StaticRandomGenerator.Next() * 21D) - 10; int randomColour = (int)(StaticRandomGenerator.Next() * 41D) - 20; for (int i = 0; i < 100; i++) { if (mapFunctionImage[i] != null) { mapFunctionImage[i].adjustRGB(randomRed + randomColour, randomGreen + randomColour, randomBlue + randomColour); } if (mapSceneImage[i] != null) { mapSceneImage[i].mixPalette(randomRed + randomColour, randomGreen + randomColour, randomBlue + randomColour); } } }
public void start(Archive streamLoader, IBaseClient client1) { String[] strings = { "model_version", "anim_version", "midi_version", "map_version" }; for (int i = 0; i < 4; i++) { byte[] abyte0 = streamLoader.decompressFile(strings[i]); int j = abyte0.Length / 2; Default317Buffer stream = new Default317Buffer(abyte0); versions[i] = new int[j]; filePriorities[i] = new byte[j]; for (int l = 0; l < j; l++) { versions[i][l] = stream.getUnsignedLEShort(); } } String[] strings2 = { "model_crc", "anim_crc", "midi_crc", "map_crc" }; for (int k = 0; k < 4; k++) { byte[] abyte1 = streamLoader.decompressFile(strings2[k]); int i1 = abyte1.Length / 4; Default317Buffer stream_1 = new Default317Buffer(abyte1); crcs[k] = new int[i1]; for (int l1 = 0; l1 < i1; l1++) { crcs[k][l1] = stream_1.getInt(); } } byte[] abyte2 = streamLoader.decompressFile("model_index"); int j1 = versions[0].Length; modelIndices = new byte[j1]; for (int k1 = 0; k1 < j1; k1++) { if (k1 < abyte2.Length) { modelIndices[k1] = abyte2[k1]; } else { modelIndices[k1] = 0; } } abyte2 = streamLoader.decompressFile("map_index"); Default317Buffer stream2 = new Default317Buffer(abyte2); j1 = abyte2.Length / 7; mapIndices1 = new int[j1]; mapIndices2 = new int[j1]; mapIndices3 = new int[j1]; mapIndices4 = new int[j1]; for (int i2 = 0; i2 < j1; i2++) { mapIndices1[i2] = stream2.getUnsignedLEShort(); mapIndices2[i2] = stream2.getUnsignedLEShort(); mapIndices3[i2] = stream2.getUnsignedLEShort(); mapIndices4[i2] = stream2.getUnsignedByte(); } abyte2 = streamLoader.decompressFile("anim_index"); stream2 = new Default317Buffer(abyte2); j1 = abyte2.Length / 2; frames = new int[j1]; for (int j2 = 0; j2 < j1; j2++) { frames[j2] = stream2.getUnsignedLEShort(); } abyte2 = streamLoader.decompressFile("midi_index"); stream2 = new Default317Buffer(abyte2); j1 = abyte2.Length; musicPriorities = new int[j1]; for (int k2 = 0; k2 < j1; k2++) { musicPriorities[k2] = stream2.getUnsignedByte(); } clientInstance = client1; running = true; clientInstance.startRunnable(this, 2); }
protected static bool IsDataAvailable(Default317Buffer dataStream) { return(dataStream.position <= dataStream.buffer.Length - 1); }
public static void unpack(Archive streamLoader, GameFont[] fonts, Archive mediaArchive) { spriteCache = new Cache(50000); Default317Buffer stream = new Default317Buffer(streamLoader.decompressFile("data")); int parentId = -1; int interfaceCount = stream.getUnsignedLEShort(); cache = new RSInterface[interfaceCount]; while (stream.position < stream.buffer.Length) { int id = stream.getUnsignedLEShort(); if (id == 65535) { parentId = stream.getUnsignedLEShort(); id = stream.getUnsignedLEShort(); } RSInterface rsInterface = cache[id] = new RSInterface(); rsInterface.id = id; rsInterface.parentID = parentId; rsInterface.type = stream.getUnsignedByte(); rsInterface.actionType = stream.getUnsignedByte(); rsInterface.contentType = stream.getUnsignedLEShort(); rsInterface.width = stream.getUnsignedLEShort(); rsInterface.height = stream.getUnsignedLEShort(); rsInterface.alpha = (byte)stream.getUnsignedByte(); rsInterface.hoveredPopup = stream.getUnsignedByte(); if (rsInterface.hoveredPopup != 0) { rsInterface.hoveredPopup = (rsInterface.hoveredPopup - 1 << 8) + stream.getUnsignedByte(); } else { rsInterface.hoveredPopup = -1; } int conditionCount = stream.getUnsignedByte(); if (conditionCount > 0) { rsInterface.conditionType = new int[conditionCount]; rsInterface.conditionValue = new int[conditionCount]; for (int c = 0; c < conditionCount; c++) { rsInterface.conditionType[c] = stream.getUnsignedByte(); rsInterface.conditionValue[c] = stream.getUnsignedLEShort(); } } int opcodeCount = stream.getUnsignedByte(); if (opcodeCount > 0) { rsInterface.opcodes = new int[opcodeCount][]; for (int c = 0; c < opcodeCount; c++) { int subOpcodeCount = stream.getUnsignedLEShort(); rsInterface.opcodes[c] = new int[subOpcodeCount]; for (int s = 0; s < subOpcodeCount; s++) { rsInterface.opcodes[c][s] = stream.getUnsignedLEShort(); } } } if (rsInterface.type == 0) { rsInterface.scrollMax = stream.getUnsignedLEShort(); rsInterface.hoverOnly = stream.getUnsignedByte() == 1; int childCount = stream.getUnsignedLEShort(); rsInterface.children = new int[childCount]; rsInterface.childX = new int[childCount]; rsInterface.childY = new int[childCount]; for (int child = 0; child < childCount; child++) { rsInterface.children[child] = stream.getUnsignedLEShort(); rsInterface.childX[child] = stream.getShort(); rsInterface.childY[child] = stream.getShort(); } } if (rsInterface.type == 1) { stream.getUnsignedLEShort(); stream.getUnsignedByte(); } if (rsInterface.type == 2) { rsInterface.inventoryItemId = new int[rsInterface.width * rsInterface.height]; rsInterface.inventoryStackSize = new int[rsInterface.width * rsInterface.height]; rsInterface.itemSwappable = stream.getUnsignedByte() == 1; rsInterface.inventory = stream.getUnsignedByte() == 1; rsInterface.usableItemInterface = stream.getUnsignedByte() == 1; rsInterface.itemDeletesDragged = stream.getUnsignedByte() == 1; rsInterface.inventorySpritePaddingColumn = stream.getUnsignedByte(); rsInterface.inventorySpritePaddingRow = stream.getUnsignedByte(); rsInterface.spritesX = new int[20]; rsInterface.spritesY = new int[20]; rsInterface.sprites = new Sprite[20]; for (int sprite = 0; sprite < 20; sprite++) { int spriteExists = stream.getUnsignedByte(); if (spriteExists == 1) { rsInterface.spritesX[sprite] = stream.getShort(); rsInterface.spritesY[sprite] = stream.getShort(); String name = stream.getString(); if (mediaArchive != null && name.Length > 0) { int spriteId = name.LastIndexOf(','); rsInterface.sprites[sprite] = getImage(int.Parse(name.Substring(spriteId + 1)), mediaArchive, name.Substring(0, spriteId)); } } } rsInterface.actions = new String[5]; for (int action = 0; action < 5; action++) { rsInterface.actions[action] = stream.getString(); if (rsInterface.actions[action].Length == 0) { rsInterface.actions[action] = null; } } } if (rsInterface.type == 3) { rsInterface.filled = stream.getUnsignedByte() == 1; } if (rsInterface.type == 4 || rsInterface.type == 1) { rsInterface.textCentred = stream.getUnsignedByte() == 1; int font = stream.getUnsignedByte(); if (fonts != null) { rsInterface.textDrawingAreas = fonts[font]; } rsInterface.textShadowed = stream.getUnsignedByte() == 1; } if (rsInterface.type == 4) { rsInterface.textDefault = stream.getString(); rsInterface.textActive = stream.getString(); } if (rsInterface.type == 1 || rsInterface.type == 3 || rsInterface.type == 4) { rsInterface.colourDefault = stream.getInt(); } if (rsInterface.type == 3 || rsInterface.type == 4) { rsInterface.colourActive = stream.getInt(); rsInterface.colourDefaultHover = stream.getInt(); rsInterface.colourActiveHover = stream.getInt(); } if (rsInterface.type == 5) { String spriteName = stream.getString(); if (mediaArchive != null && spriteName.Length > 0) { int spriteId = spriteName.LastIndexOf(","); rsInterface.spriteDefault = getImage(int.Parse(spriteName.Substring(spriteId + 1)), mediaArchive, spriteName.Substring(0, spriteId)); } spriteName = stream.getString(); if (mediaArchive != null && spriteName.Length > 0) { int spriteId = spriteName.LastIndexOf(","); rsInterface.spriteActive = getImage(int.Parse(spriteName.Substring(spriteId + 1)), mediaArchive, spriteName.Substring(0, spriteId)); } } if (rsInterface.type == 6) { int interfaceId = stream.getUnsignedByte(); if (interfaceId != 0) { rsInterface.modelTypeDefault = 1; rsInterface.modelIdDefault = (interfaceId - 1 << 8) + stream.getUnsignedByte(); } interfaceId = stream.getUnsignedByte(); if (interfaceId != 0) { rsInterface.modelTypeActive = 1; rsInterface.modelIdActive = (interfaceId - 1 << 8) + stream.getUnsignedByte(); } interfaceId = stream.getUnsignedByte(); if (interfaceId != 0) { rsInterface.animationIdDefault = (interfaceId - 1 << 8) + stream.getUnsignedByte(); } else { rsInterface.animationIdDefault = -1; } interfaceId = stream.getUnsignedByte(); if (interfaceId != 0) { rsInterface.animationIdActive = (interfaceId - 1 << 8) + stream.getUnsignedByte(); } else { rsInterface.animationIdActive = -1; } rsInterface.modelZoom = stream.getUnsignedLEShort(); rsInterface.modelRotationX = stream.getUnsignedLEShort(); rsInterface.modelRotationY = stream.getUnsignedLEShort(); } if (rsInterface.type == 7) { rsInterface.inventoryItemId = new int[rsInterface.width * rsInterface.height]; rsInterface.inventoryStackSize = new int[rsInterface.width * rsInterface.height]; rsInterface.textCentred = stream.getUnsignedByte() == 1; int font = stream.getUnsignedByte(); if (fonts != null) { rsInterface.textDrawingAreas = fonts[font]; } rsInterface.textShadowed = stream.getUnsignedByte() == 1; rsInterface.colourDefault = stream.getInt(); rsInterface.inventorySpritePaddingColumn = stream.getShort(); rsInterface.inventorySpritePaddingRow = stream.getShort(); rsInterface.inventory = stream.getUnsignedByte() == 1; rsInterface.actions = new String[5]; for (int active = 0; active < 5; active++) { rsInterface.actions[active] = stream.getString(); if (rsInterface.actions[active].Length == 0) { rsInterface.actions[active] = null; } } } if (rsInterface.actionType == 2 || rsInterface.type == 2) { rsInterface.selectedActionName = stream.getString(); rsInterface.spellName = stream.getString(); rsInterface.spellUsableOn = stream.getUnsignedLEShort(); } if (rsInterface.type == 8) { rsInterface.textDefault = stream.getString(); } if (rsInterface.actionType == 1 || rsInterface.actionType == 4 || rsInterface.actionType == 5 || rsInterface.actionType == 6) { rsInterface.tooltip = stream.getString(); if (rsInterface.tooltip.Length == 0) { if (rsInterface.actionType == 1) { rsInterface.tooltip = "Ok"; } if (rsInterface.actionType == 4) { rsInterface.tooltip = "Select"; } if (rsInterface.actionType == 5) { rsInterface.tooltip = "Select"; } if (rsInterface.actionType == 6) { rsInterface.tooltip = "Continue"; } } } } spriteCache = null; }
public IEnumerator StartupCoroutine() { if (!wasClientStartupCalled) { wasClientStartupCalled = true; } else { throw new InvalidOperationException($"Failed. Cannot call startup on Client multiple times."); } drawLoadingText(20, "Starting up"); if (clientRunning) { rsAlreadyLoaded = true; yield break; } clientRunning = true; bool validHost = true; String s = getDocumentBaseHost(); if (s.EndsWith("jagex.com")) { validHost = true; } if (s.EndsWith("runescape.com")) { validHost = true; } if (s.EndsWith("192.168.1.2")) { validHost = true; } if (s.EndsWith("192.168.1.229")) { validHost = true; } if (s.EndsWith("192.168.1.228")) { validHost = true; } if (s.EndsWith("192.168.1.227")) { validHost = true; } if (s.EndsWith("192.168.1.226")) { validHost = true; } if (s.EndsWith("127.0.0.1")) { validHost = true; } if (!validHost) { genericLoadingError = true; yield break; } if (signlink.cache_dat != null) { for (int i = 0; i < 5; i++) { caches[i] = new FileCache(signlink.cache_dat, signlink.cache_idx[i], i + 1); } } connectServer(); archiveTitle = requestArchive(1, "title screen", "title", expectedCRCs[1], 25); fontSmall = new GameFont("p11_full", archiveTitle, false); fontPlain = new GameFont("p12_full", archiveTitle, false); fontBold = new GameFont("b12_full", archiveTitle, false); GameFont fontFancy = new GameFont("q8_full", archiveTitle, true); drawLogo(); loadTitleScreen(); Archive archiveConfig = requestArchive(2, "config", "config", expectedCRCs[2], 30); Archive archiveInterface = requestArchive(3, "interface", "interface", expectedCRCs[3], 35); Archive archiveMedia = requestArchive(4, "2d graphics", "media", expectedCRCs[4], 40); Archive archiveTextures = requestArchive(6, "textures", "textures", expectedCRCs[6], 45); Archive archiveWord = requestArchive(7, "chat system", "wordenc", expectedCRCs[7], 50); Archive archiveSounds = requestArchive(8, "sound effects", "sounds", expectedCRCs[8], 55); tileFlags = new byte[4, 104, 104]; intGroundArray = CollectionUtilities.Create3DJaggedArray <int>(4, 105, 105); worldController = new WorldController(intGroundArray); for (int z = 0; z < 4; z++) { currentCollisionMap[z] = new CollisionMap(); } minimapImage = new Sprite(512, 512); Archive archiveVersions = requestArchive(5, "update list", "versionlist", expectedCRCs[5], 60); drawLoadingText(60, "Connecting to update server"); StartOnDemandFetcher(archiveVersions); Animation.init(onDemandFetcher.getAnimCount()); Model.init(onDemandFetcher.fileCount(0), onDemandFetcher); songChanging = true; onDemandFetcher.request(2, nextSong); while (onDemandFetcher.immediateRequestCount() > 0) { processOnDemandQueue(); yield return(new WaitForSeconds(0.1f)); if (onDemandFetcher.failedRequests > 3) { loadError(); yield break; } } drawLoadingText(65, "Requesting animations"); int fileRequestCount = onDemandFetcher.fileCount(1); for (int id = 0; id < fileRequestCount; id++) { onDemandFetcher.request(1, id); } while (onDemandFetcher.immediateRequestCount() > 0) { int remaining = fileRequestCount - onDemandFetcher.immediateRequestCount(); if (remaining > 0) { drawLoadingText(65, "Loading animations - " + (remaining * 100) / fileRequestCount + "%"); } try { processOnDemandQueue(); } catch (Exception e) { Console.WriteLine($"Failed to process animation demand queue. Reason: {e.Message} \n Stack: {e.StackTrace}"); signlink.reporterror($"Failed to process animation demand queue. Reason: {e.Message} \n Stack: {e.StackTrace}"); throw; } yield return(new WaitForSeconds(0.1f)); if (onDemandFetcher.failedRequests > 3) { loadError(); yield break; } } drawLoadingText(70, "Requesting models"); fileRequestCount = onDemandFetcher.fileCount(0); for (int id = 0; id < fileRequestCount; id++) { int modelId = onDemandFetcher.getModelId(id); if ((modelId & 1) != 0) { onDemandFetcher.request(0, id); } } fileRequestCount = onDemandFetcher.immediateRequestCount(); while (onDemandFetcher.immediateRequestCount() > 0) { int remaining = fileRequestCount - onDemandFetcher.immediateRequestCount(); if (remaining > 0) { drawLoadingText(70, "Loading models - " + (remaining * 100) / fileRequestCount + "%"); } processOnDemandQueue(); yield return(new WaitForSeconds(0.1f)); } GC.Collect(); if (caches[0] != null) { drawLoadingText(75, "Requesting maps"); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 47, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 47, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 48, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 48, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 49, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 49, 48)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 47, 47)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 47, 47)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 48, 47)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 48, 47)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(0, 48, 148)); yield return(null); onDemandFetcher.request(3, onDemandFetcher.getMapId(1, 48, 148)); yield return(null); fileRequestCount = onDemandFetcher.immediateRequestCount(); while (onDemandFetcher.immediateRequestCount() > 0) { int remaining = fileRequestCount - onDemandFetcher.immediateRequestCount(); if (remaining > 0) { drawLoadingText(75, "Loading maps - " + (remaining * 100) / fileRequestCount + "%"); } processOnDemandQueue(); yield return(new WaitForSeconds(0.1f)); } } fileRequestCount = onDemandFetcher.fileCount(0); for (int id = 0; id < fileRequestCount; id++) { int modelId = onDemandFetcher.getModelId(id); byte priority = 0; if ((modelId & 8) != 0) { priority = 10; } else if ((modelId & 0x20) != 0) { priority = 9; } else if ((modelId & 0x10) != 0) { priority = 8; } else if ((modelId & 0x40) != 0) { priority = 7; } else if ((modelId & 0x80) != 0) { priority = 6; } else if ((modelId & 2) != 0) { priority = 5; } else if ((modelId & 4) != 0) { priority = 4; } if ((modelId & 1) != 0) { priority = 3; } if (priority != 0) { onDemandFetcher.setPriority(priority, 0, id); } } onDemandFetcher.preloadRegions(membersWorld); //Remove low memory check. int count = onDemandFetcher.fileCount(2); for (int id = 1; id < count; id++) { if (onDemandFetcher.midiIdEqualsOne(id)) { onDemandFetcher.setPriority((byte)1, 2, id); } } drawLoadingText(80, "Unpacking media"); //Default cache can cause some errors, so wecan surpress them here. try { InitializeUnpackedMedia(archiveMedia); } catch (Exception e) { Console.WriteLine($"Media Error: {e}"); } drawLoadingText(83, "Unpacking textures"); Rasterizer.unpackTextures(archiveTextures); Rasterizer.calculatePalette(0.80000000000000004D); Rasterizer.resetTextures(); drawLoadingText(86, "Unpacking config"); AnimationSequence.unpackConfig(archiveConfig); GameObjectDefinition.load(archiveConfig); FloorDefinition.load(archiveConfig); ItemDefinition.load(archiveConfig); EntityDefinition.load(archiveConfig); IdentityKit.load(archiveConfig); SpotAnimation.load(archiveConfig); Varp.load(archiveConfig); VarBit.load(archiveConfig); ItemDefinition.membersWorld = membersWorld; //Removed low memory check drawLoadingText(90, "Unpacking sounds"); byte[] soundData = archiveSounds.decompressFile("sounds.dat"); Default317Buffer stream = new Default317Buffer(soundData); Effect.load(stream); drawLoadingText(95, "Unpacking interfaces"); GameFont[] fonts = { fontSmall, fontPlain, fontBold, fontFancy }; RSInterface.unpack(archiveInterface, fonts, archiveMedia); drawLoadingText(100, "Preparing game engine"); for (int _y = 0; _y < 33; _y++) { int firstXOfLine = 999; int lastXOfLine = 0; for (int _x = 0; _x < 34; _x++) { if (minimapBackgroundImage.pixels[_x + _y * minimapBackgroundImage.width] == 0) { if (firstXOfLine == 999) { firstXOfLine = _x; } continue; } if (firstXOfLine == 999) { continue; } lastXOfLine = _x; break; } compassHingeSize[_y] = firstXOfLine; compassWidthMap[_y] = lastXOfLine - firstXOfLine; } for (int _y = 5; _y < 156; _y++) { int min = 999; int max = 0; for (int _x = 25; _x < 172; _x++) { if (minimapBackgroundImage.pixels[_x + _y * minimapBackgroundImage.width] == 0 && (_x > 34 || _y > 34)) { if (min == 999) { min = _x; } continue; } if (min == 999) { continue; } max = _x; break; } minimapLeft[_y - 5] = min - 25; minimapLineWidth[_y - 5] = max - min; } Rasterizer.setBounds(479, 96); chatboxLineOffsets = Rasterizer.lineOffsets; Rasterizer.setBounds(190, 261); sidebarOffsets = Rasterizer.lineOffsets; Rasterizer.setBounds(512, 334); viewportOffsets = Rasterizer.lineOffsets; int[] ai = new int[9]; for (int i8 = 0; i8 < 9; i8++) { int k8 = 128 + i8 * 32 + 15; int l8 = 600 + k8 * 3; int i9 = Rasterizer.SINE[k8]; ai[i8] = l8 * i9 >> 16; } WorldController.setupViewport(500, 800, 512, 334, ai); GameObject.clientInstance = this; GameObjectDefinition.clientInstance = this; EntityDefinition.clientInstance = this; //TODO: Disabled censor //Censor.load(archiveWord); mouseDetection = new MouseDetection(this); //startRunnable(mouseDetection, 10); yield break; }
private void loadDefinition(Default317Buffer stream) { do { int opcode = stream.getUnsignedByte(); if (opcode == 0) { return; } if (opcode == 1) { int modelCount = stream.getUnsignedByte(); modelIds = new int[modelCount]; for (int m = 0; m < modelCount; m++) { modelIds[m] = stream.getUnsignedLEShort(); } } else if (opcode == 2) { name = stream.getString(); } else if (opcode == 3) { description = stream.readBytes(); } else if (opcode == 12) { boundaryDimension = stream.get(); } else if (opcode == 13) { standAnimationId = stream.getUnsignedLEShort(); } else if (opcode == 14) { walkAnimationId = stream.getUnsignedLEShort(); } else if (opcode == 17) { walkAnimationId = stream.getUnsignedLEShort(); turnAboutAnimationId = stream.getUnsignedLEShort(); turnRightAnimationId = stream.getUnsignedLEShort(); turnLeftAnimationId = stream.getUnsignedLEShort(); } else if (opcode >= 30 && opcode < 40) { if (actions == null) { actions = new String[5]; } actions[opcode - 30] = stream.getString(); if (actions[opcode - 30].Equals("hidden", StringComparison.InvariantCultureIgnoreCase)) { actions[opcode - 30] = null; } } else if (opcode == 40) { int colourCount = stream.getUnsignedByte(); modifiedModelColours = new int[colourCount]; originalModelColours = new int[colourCount]; for (int c = 0; c < colourCount; c++) { modifiedModelColours[c] = stream.getUnsignedLEShort(); originalModelColours[c] = stream.getUnsignedLEShort(); } } else if (opcode == 60) { int additionalModelCount = stream.getUnsignedByte(); headModelIds = new int[additionalModelCount]; for (int m = 0; m < additionalModelCount; m++) { headModelIds[m] = stream.getUnsignedLEShort(); } } else if (opcode == 90) { stream.getUnsignedLEShort(); } else if (opcode == 91) { stream.getUnsignedLEShort(); } else if (opcode == 92) { stream.getUnsignedLEShort(); } else if (opcode == 93) { visibleMinimap = false; } else if (opcode == 95) { combatLevel = stream.getUnsignedLEShort(); } else if (opcode == 97) { scaleXY = stream.getUnsignedLEShort(); } else if (opcode == 98) { scaleZ = stream.getUnsignedLEShort(); } else if (opcode == 99) { visible = true; } else if (opcode == 100) { brightness = stream.get(); } else if (opcode == 101) { contrast = stream.get() * 5; } else if (opcode == 102) { headIcon = stream.getUnsignedLEShort(); } else if (opcode == 103) { degreesToTurn = stream.getUnsignedLEShort(); } else if (opcode == 106) { varBitId = stream.getUnsignedLEShort(); if (varBitId == 65535) { varBitId = -1; } settingId = stream.getUnsignedLEShort(); if (settingId == 65535) { settingId = -1; } int childCount = stream.getUnsignedByte(); childrenIDs = new int[childCount + 1]; for (int c = 0; c <= childCount; c++) { childrenIDs[c] = stream.getUnsignedLEShort(); if (childrenIDs[c] == 65535) { childrenIDs[c] = -1; } } } else if (opcode == 107) { clickable = false; } } while(true); }
public void updatePlayerAppearance(Default317Buffer stream) { stream.position = 0; gender = stream.getUnsignedByte(); headIcon = stream.getUnsignedByte(); npcAppearance = null; this.team = 0; for (int slot = 0; slot < 12; slot++) { int itemId1 = stream.getUnsignedByte(); if (itemId1 == 0) { appearance[slot] = 0; continue; } int itemId2 = stream.getUnsignedByte(); appearance[slot] = (itemId1 << 8) + itemId2; if (slot == 0 && appearance[0] == 65535) { npcAppearance = EntityDefinition.getDefinition(stream.getUnsignedLEShort()); break; } if (appearance[slot] >= 512 && appearance[slot] - 512 < ItemDefinition.itemCount) { int team = ItemDefinition.getDefinition(appearance[slot] - 512).teamId; if (team != 0) { this.team = team; } } } for (int bodyPart = 0; bodyPart < 5; bodyPart++) { int colour = stream.getUnsignedByte(); if (colour < 0 || colour >= ConstantData.GetAppearanceColorRowLength(bodyPart)) { colour = 0; } bodyPartColour[bodyPart] = colour; } base.standAnimationId = stream.getUnsignedLEShort(); if (base.standAnimationId == 65535) { base.standAnimationId = -1; } base.standTurnAnimationId = stream.getUnsignedLEShort(); if (base.standTurnAnimationId == 65535) { base.standTurnAnimationId = -1; } base.walkAnimationId = stream.getUnsignedLEShort(); if (base.walkAnimationId == 65535) { base.walkAnimationId = -1; } base.turnAboutAnimationId = stream.getUnsignedLEShort(); if (base.turnAboutAnimationId == 65535) { base.turnAboutAnimationId = -1; } base.turnRightAnimationId = stream.getUnsignedLEShort(); if (base.turnRightAnimationId == 65535) { base.turnRightAnimationId = -1; } base.turnLeftAnimationId = stream.getUnsignedLEShort(); if (base.turnLeftAnimationId == 65535) { base.turnLeftAnimationId = -1; } base.runAnimationId = stream.getUnsignedLEShort(); if (base.runAnimationId == 65535) { base.runAnimationId = -1; } name = TextClass.formatName(TextClass.longToName(stream.getLong())); combatLevel = stream.getUnsignedByte(); skill = stream.getUnsignedLEShort(); visible = true; appearanceOffset = 0L; for (int slot = 0; slot < 12; slot++) { appearanceOffset <<= 4; if (appearance[slot] >= 256) { appearanceOffset += appearance[slot] - 256; } } if (appearance[0] >= 256) { appearanceOffset += appearance[0] - 256 >> 4; } if (appearance[1] >= 256) { appearanceOffset += appearance[1] - 256 >> 8; } for (int bodyPart = 0; bodyPart < 5; bodyPart++) { appearanceOffset <<= 3; appearanceOffset += bodyPartColour[bodyPart]; } appearanceOffset <<= 1; appearanceOffset += gender; }
private void loadDefinition(Default317Buffer stream) { int _actions = -1; do { int opcode; do { opcode = stream.getUnsignedByte(); if (opcode == 0) { goto label0; } if (opcode == 1) { int modelCount = stream.getUnsignedByte(); if (modelCount > 0) { if (modelIds == null || lowMemory) { modelTypes = new int[modelCount]; modelIds = new int[modelCount]; for (int m = 0; m < modelCount; m++) { modelIds[m] = stream.getUnsignedLEShort(); modelTypes[m] = stream.getUnsignedByte(); } } else { stream.position += modelCount * 3; } } } else if (opcode == 2) { name = stream.getString(); } else if (opcode == 3) { description = stream.readBytes(); } else if (opcode == 5) { int modelCount = stream.getUnsignedByte(); if (modelCount > 0) { if (modelIds == null || lowMemory) { modelTypes = null; modelIds = new int[modelCount]; for (int m = 0; m < modelCount; m++) { modelIds[m] = stream.getUnsignedLEShort(); } } else { stream.position += modelCount * 2; } } } else if (opcode == 14) { sizeX = stream.getUnsignedByte(); } else if (opcode == 15) { sizeY = stream.getUnsignedByte(); } else if (opcode == 17) { solid = false; } else if (opcode == 18) { walkable = false; } else if (opcode == 19) { _actions = stream.getUnsignedByte(); if (_actions == 1) { hasActions = true; } } else if (opcode == 21) { adjustToTerrain = true; } else if (opcode == 22) { delayShading = true; } else if (opcode == 23) { wall = true; } else if (opcode == 24) { animationId = stream.getUnsignedLEShort(); if (animationId == 65535) { animationId = -1; } } else if (opcode == 28) { offsetAmplifier = stream.getUnsignedByte(); } else if (opcode == 29) { ambient = stream.get(); } else if (opcode == 39) { diffuse = stream.get(); } else if (opcode >= 30 && opcode < 39) { if (actions == null) { actions = new String[5]; } actions[opcode - 30] = stream.getString(); if (actions[opcode - 30].Equals("hidden", StringComparison.InvariantCultureIgnoreCase)) { actions[opcode - 30] = null; } } else if (opcode == 40) { int colourCount = stream.getUnsignedByte(); modifiedModelColors = new int[colourCount]; originalModelColors = new int[colourCount]; for (int c = 0; c < colourCount; c++) { modifiedModelColors[c] = stream.getUnsignedLEShort(); originalModelColors[c] = stream.getUnsignedLEShort(); } } else if (opcode == 60) { icon = stream.getUnsignedLEShort(); } else if (opcode == 62) { rotated = true; } else if (opcode == 64) { castsShadow = false; } else if (opcode == 65) { scaleX = stream.getUnsignedLEShort(); } else if (opcode == 66) { scaleY = stream.getUnsignedLEShort(); } else if (opcode == 67) { scaleZ = stream.getUnsignedLEShort(); } else if (opcode == 68) { mapScene = stream.getUnsignedLEShort(); } else if (opcode == 69) { face = stream.getUnsignedByte(); } else if (opcode == 70) { translateX = stream.getShort(); } else if (opcode == 71) { translateY = stream.getShort(); } else if (opcode == 72) { translateZ = stream.getShort(); } else if (opcode == 73) { unknownAttribute = true; } else if (opcode == 74) { unwalkableSolid = true; } else { if (opcode != 75) { continue; } _solid = stream.getUnsignedByte(); } continue; } while(opcode != 77); varBitId = stream.getUnsignedLEShort(); if (varBitId == 65535) { varBitId = -1; } configIds = stream.getUnsignedLEShort(); if (configIds == 65535) { configIds = -1; } int childCount = stream.getUnsignedByte(); childIds = new int[childCount + 1]; for (int c = 0; c <= childCount; c++) { childIds[c] = stream.getUnsignedLEShort(); if (childIds[c] == 65535) { childIds[c] = -1; } } } while(true); label0: if (_actions == -1) { hasActions = modelIds != null && (modelTypes == null || modelTypes[0] == 10); if (actions != null) { hasActions = true; } } if (unwalkableSolid) { solid = false; walkable = false; } if (_solid == -1) { _solid = solid ? 1 : 0; } }
public Sprite(Archive streamLoader, String target, int archiveId, Default317Buffer optionalIndexStream = null) { try { if (target.ToLower() == "headicons") { return; } Default317Buffer dataStream = new Default317Buffer(streamLoader.decompressFile(target + ".dat")); Default317Buffer indexStream = optionalIndexStream != null ? optionalIndexStream : new Default317Buffer(streamLoader.decompressFile("index.dat")); indexStream.position = dataStream.getUnsignedLEShort(); maxWidth = indexStream.getUnsignedLEShort(); maxHeight = indexStream.getUnsignedLEShort(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } int length = indexStream.getUnsignedByte(); int[] pixels = new int[length]; for (int p = 0; p < length - 1; p++) { pixels[p + 1] = indexStream.get3Bytes(); if (pixels[p + 1] == 0) { pixels[p + 1] = 1; } } for (int i = 0; i < archiveId; i++) { indexStream.position += 2; dataStream.position += indexStream.getUnsignedLEShort() * indexStream.getUnsignedLEShort(); indexStream.position++; } if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } offsetX = indexStream.getUnsignedByte(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } offsetY = indexStream.getUnsignedByte(); width = indexStream.getUnsignedLEShort(); height = indexStream.getUnsignedLEShort(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } int type = indexStream.getUnsignedByte(); int pixelCount = width * height; //Custom: Below are some sanity checks that are custom but help guard against known clean cache data issues. bool isEnoughDataAvailable = pixelCount <= (dataStream.buffer.Length - dataStream.position); //Don't let corrupt image data, in default cache, cause BIG allocation (bad for WebGL) //or allocate/read for empty images. if (pixelCount <= 0 || pixelCount > int.MaxValue / 100 || !isEnoughDataAvailable || dataStream.position < 0) //sometimes happens!! { width = 0; height = 0; this.pixels = Array.Empty <int>(); return; } this.pixels = new int[pixelCount]; try { if (type == 0) { for (int p = 0; p < pixelCount; p++) { this.pixels[p] = pixels[dataStream.getUnsignedByte()]; } return; } } catch (Exception e) { Console.WriteLine($"Failed to read image type: {type}. PixelCount: {pixelCount} StreamLength: {dataStream.buffer.Length} Position: {dataStream.position} Reason: {e}"); throw; } try { if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { this.pixels[x + y * width] = pixels[dataStream.getUnsignedByte()]; } } } } catch (Exception e) { Console.WriteLine($"Failed to read image type: {type}. PixelCount: {pixelCount} Reason: {e}"); throw; } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate Sprite for: {target} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
public IndexedImage(Archive archive, String name, int id, Default317Buffer optionalMetaDataBuffer = null) { try { Default317Buffer imageBuffer = new Default317Buffer(archive.decompressFile(name + ".dat")); Default317Buffer metadataBuffer = optionalMetaDataBuffer != null ? optionalMetaDataBuffer : new Default317Buffer(archive.decompressFile("index.dat")); metadataBuffer.position = imageBuffer.getUnsignedLEShort(); resizeWidth = metadataBuffer.getUnsignedLEShort(); resizeHeight = metadataBuffer.getUnsignedLEShort(); int colourCount = metadataBuffer.getUnsignedByte(); palette = new int[colourCount]; for (int c = 0; c < colourCount - 1; c++) { palette[c + 1] = metadataBuffer.get3Bytes(); } for (int i = 0; i < id; i++) { metadataBuffer.position += 2; imageBuffer.position += metadataBuffer.getUnsignedLEShort() * metadataBuffer.getUnsignedLEShort(); metadataBuffer.position++; } drawOffsetX = metadataBuffer.getUnsignedByte(); drawOffsetY = metadataBuffer.getUnsignedByte(); width = metadataBuffer.getUnsignedLEShort(); height = metadataBuffer.getUnsignedLEShort(); int type = metadataBuffer.getUnsignedByte(); int pixelCount = width * height; //Custom: Below are some sanity checks that are custom but help guard against known clean cache data issues. bool isEnoughDataAvailable = pixelCount <= (imageBuffer.buffer.Length - imageBuffer.position); //Don't let corrupt image data, in default cache, cause BIG allocation (bad for WebGL) //or allocate/read for empty images. if (pixelCount <= 0 || pixelCount > int.MaxValue / 100 || !isEnoughDataAvailable || imageBuffer.position < 0) //sometimes happens!! { width = 0; height = 0; this.pixels = Array.Empty <byte>(); return; } pixels = new byte[pixelCount]; if (type == 0) { for (int i = 0; i < pixelCount; i++) { pixels[i] = imageBuffer.get(); } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { pixels[x + y * width] = imageBuffer.get(); } } } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate IndexedImage for: {name} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
private void readValues(Default317Buffer stream) { do { int opcode = stream.getUnsignedByte(); if (opcode == 0) { break; } if (opcode == 1) { frameCount = stream.getUnsignedByte(); primaryFrames = new int[frameCount]; secondaryFrames = new int[frameCount]; frameLengths = new int[frameCount]; for (int frame = 0; frame < frameCount; frame++) { primaryFrames[frame] = stream.getUnsignedLEShort(); secondaryFrames[frame] = stream.getUnsignedLEShort(); if (secondaryFrames[frame] == 65535) { secondaryFrames[frame] = -1; } frameLengths[frame] = stream.getUnsignedLEShort(); } } else if (opcode == 2) { frameStep = stream.getUnsignedLEShort(); } else if (opcode == 3) { int flowCount = stream.getUnsignedByte(); flowControl = new int[flowCount + 1]; for (int flow = 0; flow < flowCount; flow++) { flowControl[flow] = stream.getUnsignedByte(); } flowControl[flowCount] = 0x98967f; } else if (opcode == 4) { dynamic = true; } else if (opcode == 5) { priority = stream.getUnsignedByte(); } else if (opcode == 6) { playerReplacementShield = stream.getUnsignedLEShort(); } else if (opcode == 7) { playerReplacementWeapon = stream.getUnsignedLEShort(); } else if (opcode == 8) { maximumLoops = stream.getUnsignedByte(); } else if (opcode == 9) { /* * when animating, 0 -> block walking, 1 -> yield to walking, 2 -> interleave * with walking */ precedenceAnimating = stream.getUnsignedByte(); } else if (opcode == 10) { /* * when walking, 0 -> block walking, 1 -> yield to walking, 2 -> never used... * interleave with walking? */ precedenceWalking = stream.getUnsignedByte(); } else if (opcode == 11) { replayMode = stream.getUnsignedByte(); } else if (opcode == 12) { stream.getInt(); } else { throw new InvalidOperationException($"Error unrecognized seq config code: {opcode}"); } } while(true); if (frameCount == 0) { frameCount = 1; primaryFrames = new int[1]; primaryFrames[0] = -1; secondaryFrames = new int[1]; secondaryFrames[0] = -1; frameLengths = new int[1]; frameLengths[0] = -1; } if (precedenceAnimating == -1) { if (flowControl != null) { precedenceAnimating = 2; } else { precedenceAnimating = 0; } } if (precedenceWalking == -1) { if (flowControl != null) { precedenceWalking = 2; return; } precedenceWalking = 0; } }
private void readValues(Default317Buffer stream) { do { int opcode = stream.getUnsignedByte(); if (opcode == 0) { return; } if (opcode == 1) { modelId = stream.getUnsignedLEShort(); } else if (opcode == 2) { name = stream.getString(); } else if (opcode == 3) { description = stream.readBytes(); } else if (opcode == 4) { modelZoom = stream.getUnsignedLEShort(); } else if (opcode == 5) { modelRotationX = stream.getUnsignedLEShort(); } else if (opcode == 6) { modelRotationY = stream.getUnsignedLEShort(); } else if (opcode == 7) { modelOffset1 = stream.getUnsignedLEShort(); if (modelOffset1 > 32767) { modelOffset1 -= 0x10000; } } else if (opcode == 8) { modelOffset2 = stream.getUnsignedLEShort(); if (modelOffset2 > 32767) { modelOffset2 -= 0x10000; } } else if (opcode == 10) { stream.getUnsignedLEShort(); } else if (opcode == 11) { stackable = true; } else if (opcode == 12) { value = stream.getInt(); } else if (opcode == 16) { membersObject = true; } else if (opcode == 23) { maleEquipModelIdPrimary = stream.getUnsignedLEShort(); equipModelTranslationMale = stream.get(); } else if (opcode == 24) { maleEquipModelIdSecondary = stream.getUnsignedLEShort(); } else if (opcode == 25) { femaleEquipModelIdPrimary = stream.getUnsignedLEShort(); equipModelTranslationFemale = stream.get(); } else if (opcode == 26) { femaleEquipModelIdSecondary = stream.getUnsignedLEShort(); } else if (opcode >= 30 && opcode < 35) { if (groundActions == null) { groundActions = new String[5]; } groundActions[opcode - 30] = stream.getString(); if (groundActions[opcode - 30].Equals("hidden", StringComparison.InvariantCultureIgnoreCase)) { groundActions[opcode - 30] = null; } } else if (opcode >= 35 && opcode < 40) { if (actions == null) { actions = new String[5]; } actions[opcode - 35] = stream.getString(); } else if (opcode == 40) { int colourCount = stream.getUnsignedByte(); modifiedModelColors = new int[colourCount]; originalModelColors = new int[colourCount]; for (int c = 0; c < colourCount; c++) { modifiedModelColors[c] = stream.getUnsignedLEShort(); originalModelColors[c] = stream.getUnsignedLEShort(); } } else if (opcode == 78) { maleEquipModelIdEmblem = stream.getUnsignedLEShort(); } else if (opcode == 79) { femaleEquipModelIdEmblem = stream.getUnsignedLEShort(); } else if (opcode == 90) { maleDialogueModelId = stream.getUnsignedLEShort(); } else if (opcode == 91) { femaleDialogueModelId = stream.getUnsignedLEShort(); } else if (opcode == 92) { maleDialogueHatModelId = stream.getUnsignedLEShort(); } else if (opcode == 93) { femaleDialogueHatModelId = stream.getUnsignedLEShort(); } else if (opcode == 95) { modelRotationZ = stream.getUnsignedLEShort(); } else if (opcode == 97) { noteId = stream.getUnsignedLEShort(); } else if (opcode == 98) { noteTemplateId = stream.getUnsignedLEShort(); } else if (opcode >= 100 && opcode < 110) { if (stackableIds == null) { stackableIds = new int[10]; stackableAmounts = new int[10]; } stackableIds[opcode - 100] = stream.getUnsignedLEShort(); stackableAmounts[opcode - 100] = stream.getUnsignedLEShort(); } else if (opcode == 110) { modelScaleX = stream.getUnsignedLEShort(); } else if (opcode == 111) { modelScaleY = stream.getUnsignedLEShort(); } else if (opcode == 112) { modelScaleZ = stream.getUnsignedLEShort(); } else if (opcode == 113) { lightModifier = stream.get(); } else if (opcode == 114) { shadowModifier = stream.get() * 5; } else if (opcode == 115) { teamId = stream.getUnsignedByte(); } } while(true); }
/** * Initialise a GameFont. * * @param name The name of the font. * * @param archive The archive containing the information about the font. * * @param monospace Is the font monospace? */ public GameFont(String name, Archive archive, bool monospace) { glyphPixels = new byte[256][]; glyphWidth = new int[256]; glyphHeight = new int[256]; horizontalKerning = new int[256]; verticalKerning = new int[256]; glyphDisplayWidth = new int[256]; random = new Random(); strikethrough = false; /* * The buffer containing data about this specific font. The position of the font * within the parent archive (index.dat) and the pixel data for the glyph. */ Default317Buffer glyphData = new Default317Buffer(archive.decompressFile(name + ".dat")); /* * Stores the information about the glyphs, such as the kerning and the * dimensons. */ Default317Buffer glyphInformation = new Default317Buffer(archive.decompressFile("index.dat")); /* * Find the glyph information within the parent archive. */ glyphInformation.position = glyphData.getUnsignedLEShort() + 4; /* * Find the glyph data for this font within the parent archive. */ int startPosition = glyphInformation.getUnsignedByte(); if (startPosition > 0) { glyphInformation.position += 3 * (startPosition - 1); } /* * Get the data for each glyph. */ for (int g = 0; g < 256; g++) { horizontalKerning[g] = glyphInformation.getUnsignedByte(); verticalKerning[g] = glyphInformation.getUnsignedByte(); int width = glyphWidth[g] = glyphInformation.getUnsignedLEShort(); int height = glyphHeight[g] = glyphInformation.getUnsignedLEShort(); /* * Is the glyph rectangular? */ int rectangular = glyphInformation.getUnsignedByte(); /* * Get the area of the glyph. */ int area = width * height; /* * Initialise the pixels for this glyph. */ glyphPixels[g] = new byte[area]; /* * Set the pixels for the glyph based on whether it is square or rectangular. */ if (rectangular == 0) { for (int p = 0; p < area; p++) { glyphPixels[g][p] = glyphData.get(); } } else if (rectangular == 1) { for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { glyphPixels[g][w + h * width] = glyphData.get(); } } } /* * If the height of this glyph is higher than the highest glyph we've currently * processed for this font, store this glyph's height as the highest. * * 126 is the last visible character used in this client (~). No support for * accented characters! */ if (height > fontHeight && g < 128) { fontHeight = height; } horizontalKerning[g] = 1; glyphDisplayWidth[g] = width + 2; int activePixels = 0; for (int h = height / 7; h < height; h++) { activePixels += glyphPixels[g][h * width]; } if (activePixels <= height / 7) { glyphDisplayWidth[g]--; horizontalKerning[g] = 0; } activePixels = 0; for (int h = height / 7; h < height; h++) { activePixels += glyphPixels[g][(width - 1) + h * width]; } if (activePixels <= height / 7) { glyphDisplayWidth[g]--; } } /* * Character 32 is space, character 73 is uppercase I and character 105 is * lowercase i. */ if (monospace) { glyphDisplayWidth[32] = glyphDisplayWidth[73]; } else { glyphDisplayWidth[32] = glyphDisplayWidth[105]; } }