Skip to content

Instantly share code, notes, and snippets.

@civet
Created April 9, 2021 07:33
Show Gist options
  • Save civet/c45006b6f4c9be40fc7dce5fc337787e to your computer and use it in GitHub Desktop.
Save civet/c45006b6f4c9be40fc7dce5fc337787e to your computer and use it in GitHub Desktop.
controllable AVM1Movie
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class AVM2Loader extends Loader
{
private var _stream: URLStream;
private var _context: LoaderContext;
public function AVM2Loader()
{
_stream = new URLStream();
_stream.addEventListener(Event.COMPLETE, onLoadComplete);
super();
}
private function onLoadComplete(event: Event): void
{
var bytes: ByteArray = new ByteArray();
_stream.readBytes(bytes);
_stream.close();
this.loadBytes(bytes, _context);
}
override public function load(request: URLRequest, context: LoaderContext = null):void
{
_context = context;
_stream.load(request);
}
override public function loadBytes(bytes: ByteArray, context: LoaderContext = null):void
{
bytes.endian = Endian.LITTLE_ENDIAN;
// uncompress if compressed
if(bytes[0] == 0x43) {
var compressedBytes: ByteArray = new ByteArray();
compressedBytes.writeBytes(bytes, 8);
compressedBytes.uncompress();
bytes.length = 8;
bytes.position = 8;
bytes.writeBytes(compressedBytes);
// flag uncompressed
bytes[0] = 0x46;
compressedBytes.clear();
}
var pos: int = 0;
var version:uint = uint(bytes[3]);
if(version < 9) {
bytes[3] = 9;
}
if(version > 7) {
pos = this.findPos(13 + (5 + (bytes[8] >>> 3) * 4) / 8,bytes);
if(pos != -1) {
bytes[pos + 2] |= 8;
}
else {
this.insertTag(bytes);
}
}
else {
this.insertTag(bytes);
}
super.loadBytes(bytes, context);
}
private function insertTag(bytes: ByteArray) : void
{
var pos: uint = 13 + (5 + (bytes[8] >>> 3) * 4) / 8;
var afterBytes: ByteArray = new ByteArray();
afterBytes.writeBytes(bytes,pos);
bytes.length = pos;
bytes.position = pos;
bytes.writeByte(0x44);
bytes.writeByte(0x11);
bytes.writeByte(0x08);
bytes.writeByte(0);
bytes.writeByte(0);
bytes.writeByte(0);
bytes.writeBytes(afterBytes);
afterBytes.length = 0;
}
private function findPos(offset: uint, bytes: ByteArray): int
{
var byte: uint = 0;
var length: uint = 0;
bytes.position = offset;
try
{
while(true)
{
byte = bytes.readShort();
if(byte >>> 6 == 69) {
return bytes.position - 2;
}
length = byte & 63;
if(length == 63) {
length = bytes.readInt();
}
bytes.position += length;
}
}
catch(e:Error) {
}
return -1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment