mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-20 10:06:15 +00:00
Reorder scripts and classes to be in position as original script.
This commit is contained in:
@@ -1266,6 +1266,50 @@ public class ABC {
|
||||
}
|
||||
}
|
||||
|
||||
public void reorganizeClasses(Map<Integer, Integer> classIndexMap) {
|
||||
for (MethodBody b : bodies) {
|
||||
for (AVM2Instruction ins : b.getCode().code) {
|
||||
for (int i = 0; i < ins.definition.operands.length; i++) {
|
||||
if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) {
|
||||
if (classIndexMap.containsKey(ins.operands[i])) {
|
||||
ins.setOperand(i, classIndexMap.get(ins.operands[i]), b.getCode(), b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ScriptInfo si : script_info) {
|
||||
reorganizeClassesInTraits(si.traits, classIndexMap);
|
||||
}
|
||||
for (MethodBody b : bodies) {
|
||||
reorganizeClassesInTraits(b.traits, classIndexMap);
|
||||
}
|
||||
Map<Integer, InstanceInfo> backupInstanceInfos = new HashMap<>();
|
||||
Map<Integer, ClassInfo> backupClassInfos = new HashMap<>();
|
||||
for (int from : classIndexMap.keySet()) {
|
||||
backupInstanceInfos.put(from, instance_info.get(from));
|
||||
backupClassInfos.put(from, class_info.get(from));
|
||||
}
|
||||
for (int from : classIndexMap.keySet()) {
|
||||
int to = classIndexMap.get(from);
|
||||
instance_info.set(to, backupInstanceInfos.get(from));
|
||||
class_info.set(to, backupClassInfos.get(from));
|
||||
}
|
||||
}
|
||||
|
||||
private void reorganizeClassesInTraits(Traits traits, Map<Integer, Integer> classIndexMap) {
|
||||
for (Trait t : traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
TraitClass tc = (TraitClass) t;
|
||||
reorganizeClassesInTraits(instance_info.get(tc.class_info).instance_traits, classIndexMap);
|
||||
reorganizeClassesInTraits(class_info.get(tc.class_info).static_traits, classIndexMap);
|
||||
if (classIndexMap.containsKey(tc.class_info)) {
|
||||
tc.class_info = classIndexMap.get(tc.class_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeClass(int index) {
|
||||
for (MethodBody b : bodies) {
|
||||
for (AVM2Instruction ins : b.getCode().code) {
|
||||
|
||||
@@ -5,6 +5,8 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter;
|
||||
@@ -22,7 +24,10 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class As3ScriptReplacer extends MxmlcRunner {
|
||||
|
||||
@@ -152,7 +157,18 @@ public class As3ScriptReplacer extends MxmlcRunner {
|
||||
try (FileInputStream fis = new FileInputStream(compiledSwfFile)) {
|
||||
SWF newSWF = new SWF(fis, false, false);
|
||||
List<ABCContainerTag> newTags = newSWF.getAbcList();
|
||||
int oldScriptIndex = oldPack.scriptIndex;
|
||||
int oldClassIndex = -1;
|
||||
|
||||
ScriptInfo oldScriptInfo = oldPack.abc.script_info.get(oldPack.scriptIndex);
|
||||
for (Trait t : oldScriptInfo.traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
int traitClassIndex = ((TraitClass) t).class_info;
|
||||
if (oldClassIndex == -1 || traitClassIndex < oldClassIndex) {
|
||||
oldClassIndex = traitClassIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldPack.isSimple) {
|
||||
oldScriptInfo.delete(oldPack.abc, true);
|
||||
} else {
|
||||
@@ -161,8 +177,65 @@ public class As3ScriptReplacer extends MxmlcRunner {
|
||||
oldPack.abc.pack(); // removes old classes/methods/scripts
|
||||
ABCContainerTag newTagsLast = newTags.get(newTags.size() - 1);
|
||||
ABC newLastAbc = newTagsLast.getABC();
|
||||
oldPack.abc.mergeABC(newLastAbc);
|
||||
//TODO: reorder classes
|
||||
Map<Integer, Integer> classesMap = new HashMap<>();
|
||||
Map<Integer, Integer> scriptsMap = new HashMap<>();
|
||||
|
||||
oldPack.abc.mergeABC(newLastAbc,
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
classesMap,
|
||||
new HashMap<>(),
|
||||
scriptsMap
|
||||
);
|
||||
|
||||
//Reorder newly created scripts to be in place
|
||||
//where old script was
|
||||
List<Integer> addedScriptIndices = new ArrayList<>(scriptsMap.values());
|
||||
Collections.sort(addedScriptIndices);
|
||||
List<ScriptInfo> addedScripts = new ArrayList<>();
|
||||
for (int i = addedScriptIndices.size() - 1; i >= 0; i--) {
|
||||
int newScriptIndex = addedScriptIndices.get(i);
|
||||
addedScripts.add(0, oldPack.abc.script_info.remove(newScriptIndex));
|
||||
}
|
||||
for (int i = 0; i < addedScripts.size(); i++) {
|
||||
oldPack.abc.script_info.add(oldScriptIndex + i, addedScripts.get(i));
|
||||
}
|
||||
|
||||
//IMPORTANT: Map newly created classes to their position as they
|
||||
//were in original script because FlashPlayer needs
|
||||
//parent class to be defined earlier
|
||||
if (oldClassIndex > -1) {
|
||||
List<Integer> addedClassIndices = new ArrayList<>(classesMap.values());
|
||||
Collections.sort(addedClassIndices);
|
||||
int totalClassCount = oldPack.abc.class_info.size();
|
||||
Map<Integer, Integer> classesRemap = new HashMap<>();
|
||||
for (int i = 0; i < addedClassIndices.size(); i++) {
|
||||
classesRemap.put(addedClassIndices.get(i), oldClassIndex + i);
|
||||
}
|
||||
int mappingStart = oldClassIndex;
|
||||
for (int i = oldClassIndex; i < totalClassCount; i++) {
|
||||
if (!classesRemap.containsKey(i)) {
|
||||
for (int j = mappingStart; j < totalClassCount; j++) {
|
||||
if (!classesRemap.containsValue(j)) {
|
||||
classesRemap.put(i, j);
|
||||
mappingStart = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
oldPack.abc.reorganizeClasses(classesRemap);
|
||||
}
|
||||
((Tag) oldPack.abc.parentTag).setModified(true);
|
||||
}
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user