Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package me.Zero2.filepatcher;
- import java.awt.Font;
- import java.io.File;
- import java.io.RandomAccessFile;
- import javax.swing.JButton;
- import javax.swing.JFileChooser;
- import javax.swing.JFrame;
- public class Main {
- public static void patchFile(File file,boolean guiSuccess) { //the works
- try {
- System.out.print("Patching file \"" + file.getPath() + "\"...");
- long indexOffset = readUnsignedInt32(0x10,file); //Let's first find the index offset. You'll find this at offset 0x10 from ALL Halo full maps.
- long magic = readUnsignedInt32(indexOffset,file) - indexOffset - 0x28; //We go to the index offset, subtract 0x28 to get Magic, and then subtract Index Offset to get the Map Magic which is what we need.
- long numberOfTags = readUnsignedInt32(indexOffset + 0xC,file); //Now we need to know how many tags there are. I don't know WHY it's a long since no unmodded map has that many tags.
- long tagArrayOffset = indexOffset + 0x28; //Now we need to get to the tag array offset. It's 0x28 from the index offset.
- boolean name = false;
- boolean description = false;
- for(int i=0;i<numberOfTags;i++) { //We need to analyze every tag's name, until we get to the tag we want.
- long currentLocation = 0x20*i + tagArrayOffset;
- long nameOffset = readUnsignedInt32(currentLocation + 0x10,file) - magic;
- if(read4ByteUTF8(currentLocation,file).equals("rtsu")) { //It's the correct type, but is it the correct name?
- if(readUTF8(nameOffset,file).equals("ui\\shell\\main_menu\\mp_map_list")) { //we've found the tag we want. Yay!
- long namesOffset = readUnsignedInt32(currentLocation + 0x14,file) - magic + 0x1B0;
- long boardingActionOffset = namesOffset + 0xB4;
- changeUTF16String(boardingActionOffset,file,"Barrier",15); //changeUTF16String(long offset,File file,String changeTo,int maximumLength);
- long chironOffset = boardingActionOffset + 0x48;
- changeUTF16String(chironOffset,file,"The Shaft",11);
- long gephyOffset = chironOffset + 0xA4;
- changeUTF16String(gephyOffset,file,"Modded",13);
- long infinityOffset = gephyOffset - 0x2C;
- changeUTF16String(infinityOffset,file,"Crossing",8);
- name = true;
- }
- if(readUTF8(nameOffset,file).equals("ui\\shell\\main_menu\\multiplayer_type_select\\mp_map_select\\map_data")) { //we've found the tag we want. Yay!
- long descriptionOffset = readUnsignedInt32(currentLocation + 0x14,file) - magic + 0x19C;
- long boardingActionOffset = descriptionOffset + 0x2BC;
- changeUTF16String(boardingActionOffset,file,"Trapped!\n\n6-12 players",0x24);
- long chironOffset = boardingActionOffset + 0x120;
- changeUTF16String(chironOffset,file,"Your deepest grave\n\n8-16 players",0x2E);
- long infinityOffset = chironOffset + 0x258;
- changeUTF16String(infinityOffset,file,"In space, no one\ncan hear you scream\n\n6-12 players",0x48);
- long gephyOffset = infinityOffset + 0x10C;
- changeUTF16String(gephyOffset,file,"",0x32);
- description = true;
- }
- }
- }
- if(name && description) {
- System.out.println("Done!");
- if(guiSuccess) notification("Done!");
- }
- if(!name && !description) {
- System.out.println("Name and description tag was not found! Is this map protected?");
- if(guiSuccess) notification("The name and description tags could not be found! Protected?");
- }
- if(!name) {
- System.out.println("Names tag not found!");
- if(guiSuccess) notification("The maps' names tag wasn't found.");
- }
- if(!description) {
- System.out.println("Descriptions tag was not found!");
- if(guiSuccess) notification("The maps' descriptions tag wasn't found.");
- }
- }
- catch(Exception e) {
- e.printStackTrace();
- System.out.println("Error!");
- if(guiSuccess) notification("The map could not be opened!");
- }
- }
- public static void changeUTF16String(long offset,File file,String text, int length) throws Exception { //change string, null remaining data based on Length.
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- int reduce = 0;
- int i=0;
- for(; i<length; i++) {
- raf.seek(offset + i * 2);
- if(i+reduce<text.length()) {
- if(text.toCharArray()[i + reduce] == (char)0xA) {
- raf.writeByte(0x0D);
- i++;
- if(i < length) {
- raf.seek(offset + i*2);
- raf.writeByte(0x0A);
- }
- reduce--;
- }
- else raf.writeByte(text.toCharArray()[i + reduce]);
- } else {
- raf.seek(offset + i * 2);
- raf.writeByte(0);
- }
- }
- raf.close();
- }
- public static long readUnsignedInt32(long offset, File file) throws Exception {
- RandomAccessFile raf = new RandomAccessFile(file, "r"); //loads the file for reading
- int[] b = new int[4];
- for(int i=0;i<4;i++) {
- raf.seek(offset+i);
- b[i] = raf.readByte();
- if(b[i] < 0) b[i] += Byte.MAX_VALUE*2+2;
- }
- raf.close(); //closes
- long value = b[0]; //convert to big endian
- value += b[1]*256;
- value += b[2]*256*256;
- value += b[3]*256*256*((long)256);
- return value;
- }
- public static String readUTF8(long offset, File file) throws Exception { //reads a UTF-8 string until a terminating 0
- RandomAccessFile raf = new RandomAccessFile(file, "r");
- String returnValue = "";
- boolean terminate = false;
- for(int i=0;!terminate;i++) {
- raf.seek(offset+i);
- returnValue += (char)raf.readByte();
- if(raf.readByte() == 0) terminate = true;
- }
- raf.close();
- return returnValue;
- }
- public static String read4ByteUTF8(long offset, File file) throws Exception { //reads only 4 bytes for tag class
- RandomAccessFile raf = new RandomAccessFile(file, "r"); //read only
- String returnValue = "";
- for(int i=0;i<4;i++) {
- raf.seek(offset+i);
- returnValue += (char)raf.readByte();
- }
- raf.close();
- return returnValue;
- }
- public static void main(String[] args) {
- if(args.length != 0) {
- for(String string : args) patchFile(new File(string),false);
- return;
- }
- JFileChooser dialogue = new JFileChooser();
- dialogue.showOpenDialog(null);
- try {
- if(dialogue.getSelectedFile() == null) return;
- patchFile(dialogue.getSelectedFile(),true);
- } catch (Exception e) {
- System.out.println("Failed.");
- }
- }
- public static void notification(String message) {
- final JFrame frame2 = new JFrame();
- frame2.setBounds(100, 100, 250, 100);
- frame2.setLocationRelativeTo(null);
- frame2.setTitle("Result");
- JButton label2 = new JButton(message);
- label2.setFont(Font.getFont(Font.SANS_SERIF));
- label2.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent e) {
- frame2.dispose();
- }
- });
- frame2.add(label2);
- frame2.setVisible(true);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement