L2ClientDat decoder.
This commit is contained in:
403
L2ClientDat/java/com/l2jmobius/L2ClientDat.java
Normal file
403
L2ClientDat/java/com/l2jmobius/L2ClientDat.java
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
|
||||
import com.l2jmobius.actions.MassRecryptor;
|
||||
import com.l2jmobius.actions.MassTxtPacker;
|
||||
import com.l2jmobius.actions.MassTxtUnpacker;
|
||||
import com.l2jmobius.actions.OpenDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.config.ConfigWindow;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.forms.JPopupTextArea;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.util.Util;
|
||||
import com.l2jmobius.xml.CryptVersionParser;
|
||||
import com.l2jmobius.xml.Descriptor;
|
||||
import com.l2jmobius.xml.DescriptorParser;
|
||||
import com.l2jmobius.xml.DescriptorWriter;
|
||||
|
||||
public class L2ClientDat extends JFrame
|
||||
{
|
||||
private static JPopupTextArea textPaneLog;
|
||||
private static JPopupTextArea textPaneMain;
|
||||
private static JComboBox<String> jComboBoxChronicle;
|
||||
private static JComboBox<String> jComboBoxDecrypt;
|
||||
private static JComboBox<String> jComboBoxEncrypt;
|
||||
private static File currentFileWindow;
|
||||
|
||||
public L2ClientDat()
|
||||
{
|
||||
setTitle("L2ClientDat decoder");
|
||||
setMinimumSize(new Dimension(1000, 600));
|
||||
this.setSize(new Dimension(ConfigWindow.WINDOW_WIDTH, ConfigWindow.WINDOW_HEIGHT));
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
setDefaultCloseOperation(3);
|
||||
setLocationRelativeTo(null);
|
||||
addWindowListener(new WindowAdapter()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent evt)
|
||||
{
|
||||
ConfigWindow.save("WINDOW_HEIGHT", String.valueOf(L2ClientDat.this.getHeight()));
|
||||
ConfigWindow.save("WINDOW_WIDTH", String.valueOf(L2ClientDat.this.getWidth()));
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new BorderLayout());
|
||||
JPanel buttonPane0 = new JPanel();
|
||||
JLabel structureLabel = new JLabel("structure:");
|
||||
buttonPane0.add(structureLabel);
|
||||
jComboBoxChronicle = new JComboBox<>();
|
||||
jComboBoxChronicle.setModel(new DefaultComboBoxModel<>(Util.getFilesNames("./structure/", ".xml")));
|
||||
jComboBoxChronicle.setSelectedItem(ConfigWindow.CURRENT_CHRONICLE);
|
||||
jComboBoxChronicle.addActionListener(e -> saveComboBox(jComboBoxChronicle, "CURRENT_CHRONICLE"));
|
||||
buttonPane0.add(jComboBoxChronicle);
|
||||
JLabel decryptLabel = new JLabel("decrypt:");
|
||||
buttonPane0.add(decryptLabel);
|
||||
jComboBoxDecrypt = new JComboBox<>();
|
||||
jComboBoxDecrypt.setModel(new DefaultComboBoxModel<>(CryptVersionParser.getInstance().getDecryptKeys().keySet().toArray(new String[CryptVersionParser.getInstance().getDecryptKeys().keySet().size()])));
|
||||
jComboBoxDecrypt.setSelectedItem(ConfigWindow.CURRENT_DECRYPT);
|
||||
jComboBoxDecrypt.addActionListener(e -> saveComboBox(jComboBoxDecrypt, "CURRENT_DECRYPT"));
|
||||
buttonPane0.add(jComboBoxDecrypt);
|
||||
JLabel encryptLabel = new JLabel("encrypt:");
|
||||
buttonPane0.add(encryptLabel);
|
||||
jComboBoxEncrypt = new JComboBox<>();
|
||||
jComboBoxEncrypt.setModel(new DefaultComboBoxModel<>(CryptVersionParser.getInstance().getEncryptKey().keySet().toArray(new String[CryptVersionParser.getInstance().getDecryptKeys().keySet().size()])));
|
||||
jComboBoxEncrypt.setSelectedItem(ConfigWindow.CURRENT_ENCRYPT);
|
||||
jComboBoxEncrypt.addActionListener(e -> saveComboBox(jComboBoxEncrypt, "CURRENT_ENCRYPT"));
|
||||
buttonPane0.add(jComboBoxEncrypt);
|
||||
buttonPane.add(buttonPane0, "First");
|
||||
JPanel buttonPane1 = new JPanel();
|
||||
JButton open = new JButton();
|
||||
open.setText("Open");
|
||||
open.addActionListener(this::openSelectFileWindow);
|
||||
buttonPane1.add(open);
|
||||
JButton save = new JButton();
|
||||
save.setText("Save txt");
|
||||
save.addActionListener(this::saveActionPerformed);
|
||||
buttonPane1.add(save);
|
||||
JButton saveAs = new JButton();
|
||||
saveAs.setText("Save dat");
|
||||
saveAs.addActionListener(this::saveAsActionPerformed);
|
||||
buttonPane1.add(saveAs);
|
||||
JButton massTxtUnpack = new JButton();
|
||||
massTxtUnpack.setText("Extract all to txt");
|
||||
massTxtUnpack.addActionListener(this::massTxtUnpackActionPerformed);
|
||||
buttonPane1.add(massTxtUnpack);
|
||||
JButton massTxtPack = new JButton();
|
||||
massTxtPack.setText("Download all dat");
|
||||
massTxtPack.addActionListener(this::massTxtPackActionPerformed);
|
||||
buttonPane1.add(massTxtPack);
|
||||
JButton massRecrypt = new JButton();
|
||||
massRecrypt.setText("Patch dat");
|
||||
massRecrypt.addActionListener(this::massRecryptActionPerformed);
|
||||
buttonPane1.add(massRecrypt);
|
||||
buttonPane.add(buttonPane1);
|
||||
JSplitPane jsp = new JSplitPane(0, false);
|
||||
jsp.setResizeWeight(0.7);
|
||||
jsp.setOneTouchExpandable(true);
|
||||
textPaneMain = new JPopupTextArea();
|
||||
textPaneMain.setBackground(new Color(41, 49, 52));
|
||||
textPaneMain.setForeground(Color.WHITE);
|
||||
textPaneMain.setFont(new Font("Verdana", 1, 12));
|
||||
JScrollPane jScrollPane1 = new JScrollPane();
|
||||
jScrollPane1.setAutoscrolls(true);
|
||||
jScrollPane1.setViewportView(textPaneMain);
|
||||
jsp.setTopComponent(jScrollPane1);
|
||||
textPaneLog = new JPopupTextArea();
|
||||
textPaneLog.setBackground(new Color(41, 49, 52));
|
||||
textPaneLog.setForeground(Color.GREEN);
|
||||
textPaneLog.setEditable(false);
|
||||
JScrollPane jScrollPane2 = new JScrollPane();
|
||||
jScrollPane2.setViewportView(textPaneLog);
|
||||
jScrollPane2.setAutoscrolls(true);
|
||||
jsp.setBottomComponent(jScrollPane2);
|
||||
getContentPane().add(buttonPane, "First");
|
||||
getContentPane().add(jsp);
|
||||
pack();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void massTxtPackActionPerformed(ActionEvent evt)
|
||||
{
|
||||
JFileChooser fileopen = new JFileChooser();
|
||||
fileopen.setFileSelectionMode(1);
|
||||
fileopen.setAcceptAllFileFilterUsed(false);
|
||||
fileopen.setCurrentDirectory(new File(ConfigWindow.FILE_OPEN_CURRENT_DIRECTORY_PACK));
|
||||
fileopen.setPreferredSize(new Dimension(600, 600));
|
||||
int ret = fileopen.showDialog(null, "Open");
|
||||
if (ret == 0)
|
||||
{
|
||||
currentFileWindow = fileopen.getSelectedFile();
|
||||
ConfigWindow.save("FILE_OPEN_CURRENT_DIRECTORY_PACK", currentFileWindow.getPath());
|
||||
L2ClientDat.addLogConsole("---------------------------------------", true);
|
||||
L2ClientDat.addLogConsole("selected folder: " + currentFileWindow.getPath(), true);
|
||||
try
|
||||
{
|
||||
MassTxtPacker.getInstance().pack(String.valueOf(jComboBoxChronicle.getSelectedItem()), currentFileWindow.getPath(), CryptVersionParser.getInstance().getEncryptKey(String.valueOf(jComboBoxEncrypt.getSelectedItem())));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(L2ClientDat.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void massTxtUnpackActionPerformed(ActionEvent evt)
|
||||
{
|
||||
JFileChooser fileopen = new JFileChooser();
|
||||
fileopen.setFileSelectionMode(1);
|
||||
fileopen.setAcceptAllFileFilterUsed(false);
|
||||
fileopen.setCurrentDirectory(new File(ConfigWindow.FILE_OPEN_CURRENT_DIRECTORY_UNPACK));
|
||||
fileopen.setPreferredSize(new Dimension(600, 600));
|
||||
int ret = fileopen.showDialog(null, "Open");
|
||||
if (ret == 0)
|
||||
{
|
||||
currentFileWindow = fileopen.getSelectedFile();
|
||||
ConfigWindow.save("FILE_OPEN_CURRENT_DIRECTORY_UNPACK", currentFileWindow.getPath());
|
||||
L2ClientDat.addLogConsole("---------------------------------------", true);
|
||||
L2ClientDat.addLogConsole("selected folder: " + currentFileWindow.getPath(), true);
|
||||
try
|
||||
{
|
||||
MassTxtUnpacker.getInstance().unpack(String.valueOf(jComboBoxChronicle.getSelectedItem()), currentFileWindow.getPath(), CryptVersionParser.getInstance().getDecryptKey(String.valueOf(jComboBoxDecrypt.getSelectedItem())));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(L2ClientDat.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void massRecryptActionPerformed(ActionEvent evt)
|
||||
{
|
||||
JFileChooser fileopen = new JFileChooser();
|
||||
fileopen.setFileSelectionMode(1);
|
||||
fileopen.setAcceptAllFileFilterUsed(false);
|
||||
fileopen.setCurrentDirectory(new File(ConfigWindow.FILE_OPEN_CURRENT_DIRECTORY));
|
||||
fileopen.setPreferredSize(new Dimension(600, 600));
|
||||
int ret = fileopen.showDialog(null, "Open");
|
||||
if (ret == 0)
|
||||
{
|
||||
currentFileWindow = fileopen.getSelectedFile();
|
||||
ConfigWindow.save("FILE_OPEN_CURRENT_DIRECTORY", currentFileWindow.getPath());
|
||||
L2ClientDat.addLogConsole("---------------------------------------", true);
|
||||
L2ClientDat.addLogConsole("selected folder: " + currentFileWindow.getPath(), true);
|
||||
try
|
||||
{
|
||||
MassRecryptor.getInstance().recrypt(String.valueOf(jComboBoxChronicle.getSelectedItem()), currentFileWindow.getPath(), CryptVersionParser.getInstance().getDecryptKey(String.valueOf(jComboBoxDecrypt.getSelectedItem())), CryptVersionParser.getInstance().getEncryptKey(String.valueOf(jComboBoxEncrypt.getSelectedItem())));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(L2ClientDat.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openSelectFileWindow(ActionEvent evt)
|
||||
{
|
||||
textPaneMain.removeAll();
|
||||
JFileChooser fileopen = new JFileChooser();
|
||||
fileopen.setFileSelectionMode(0);
|
||||
fileopen.setAcceptAllFileFilterUsed(false);
|
||||
fileopen.setFileFilter(new FileNameExtensionFilter(".dat, .ini, .txt, .htm", "dat", "ini", "txt", "htm"));
|
||||
fileopen.setSelectedFile(new File(ConfigWindow.LAST_FILE_SELECTED));
|
||||
fileopen.setPreferredSize(new Dimension(600, 600));
|
||||
int ret = fileopen.showDialog(null, "Open");
|
||||
if (ret == 0)
|
||||
{
|
||||
currentFileWindow = fileopen.getSelectedFile();
|
||||
ConfigWindow.save("LAST_FILE_SELECTED", currentFileWindow.getAbsolutePath());
|
||||
L2ClientDat.addLogConsole("---------------------------------------", true);
|
||||
L2ClientDat.addLogConsole("Open file: " + currentFileWindow.getName(), true);
|
||||
try
|
||||
{
|
||||
OpenDat.start(String.valueOf(jComboBoxChronicle.getSelectedItem()), currentFileWindow, currentFileWindow.getName(), CryptVersionParser.getInstance().getDecryptKey(String.valueOf(jComboBoxDecrypt.getSelectedItem())));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(L2ClientDat.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveActionPerformed(ActionEvent evt)
|
||||
{
|
||||
JFileChooser fileSave = new JFileChooser();
|
||||
fileSave.setCurrentDirectory(new File(ConfigWindow.FILE_SAVE_CURRENT_DIRECTORY));
|
||||
if (currentFileWindow != null)
|
||||
{
|
||||
fileSave.setSelectedFile(new File(currentFileWindow.getName().split("\\.")[0] + ".txt"));
|
||||
fileSave.setFileFilter(new FileNameExtensionFilter(".txt", "txt"));
|
||||
fileSave.setAcceptAllFileFilterUsed(false);
|
||||
fileSave.setPreferredSize(new Dimension(600, 600));
|
||||
int ret = fileSave.showSaveDialog(null);
|
||||
if (ret == 0)
|
||||
{
|
||||
File f = fileSave.getSelectedFile();
|
||||
try
|
||||
{
|
||||
PrintWriter out = new PrintWriter(new FileOutputStream(f.getPath()), true);
|
||||
ConfigWindow.save("FILE_SAVE_CURRENT_DIRECTORY", f.getParentFile().toString());
|
||||
out.print(textPaneMain.getText());
|
||||
out.close();
|
||||
}
|
||||
catch (Exception out)
|
||||
{
|
||||
// empty catch block
|
||||
}
|
||||
L2ClientDat.addLogConsole("---------------------------------------", true);
|
||||
L2ClientDat.addLogConsole("Saved: " + f.getPath(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L2ClientDat.addLogConsole("No open file!", true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enabled aggressive block sorting Enabled unnecessary exception pruning Enabled aggressive exception aggregation
|
||||
*/
|
||||
private void saveAsActionPerformed(ActionEvent evt)
|
||||
{
|
||||
if (currentFileWindow == null)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Error saving dat. No file name.", true);
|
||||
return;
|
||||
}
|
||||
byte[] buff = null;
|
||||
DatCrypter crypter = null;
|
||||
if (currentFileWindow.getName().endsWith(".dat") || currentFileWindow.getName().endsWith(".txt"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Descriptor desc = DescriptorParser.getInstance().findDescriptorForFile(String.valueOf(jComboBoxChronicle.getSelectedItem()), currentFileWindow.getName().replace("txt", "dat"));
|
||||
if (desc != null)
|
||||
{
|
||||
crypter = CryptVersionParser.getInstance().getEncryptKey(String.valueOf(jComboBoxEncrypt.getSelectedItem()));
|
||||
buff = DescriptorWriter.parseData(currentFileWindow, crypter, desc, textPaneMain.getText());
|
||||
GameDataName.getInstance().checkAndUpdate(currentFileWindow.getParent(), crypter);
|
||||
}
|
||||
L2ClientDat.addLogConsole("Not found the structure of the file: " + currentFileWindow.getName(), true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (currentFileWindow.getName().endsWith(".ini"))
|
||||
{
|
||||
crypter = CryptVersionParser.getInstance().getEncryptKey(String.valueOf(jComboBoxEncrypt.getSelectedItem()));
|
||||
buff = textPaneMain.getText().getBytes();
|
||||
}
|
||||
if (buff == null)
|
||||
{
|
||||
L2ClientDat.addLogConsole("buff == null.", true);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (ConfigDebug.ENCRYPT && (crypter != null))
|
||||
{
|
||||
DatFile.encrypt(buff, currentFileWindow.getPath(), crypter);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
L2ClientDat.addLogConsole("Packed successfully.", true);
|
||||
}
|
||||
|
||||
private void saveComboBox(JComboBox<?> jComboBox, String param)
|
||||
{
|
||||
ConfigWindow.save(param, String.valueOf(jComboBox.getSelectedItem()));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
ConfigWindow.load();
|
||||
ConfigDebug.load();
|
||||
CryptVersionParser.getInstance();
|
||||
Util.compileJavaClass("./structure/format/");
|
||||
DescriptorParser.getInstance();
|
||||
try
|
||||
{
|
||||
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
|
||||
{
|
||||
if (!"Nimbus".equals(info.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
UIManager.setLookAndFeel(info.getClassName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(L2ClientDat.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
EventQueue.invokeLater(L2ClientDat::new);
|
||||
}
|
||||
|
||||
public static void addLogConsole(String log, boolean isLog)
|
||||
{
|
||||
if (isLog)
|
||||
{
|
||||
DebugUtil.getLogger().info(log);
|
||||
}
|
||||
textPaneLog.append(log + "\n");
|
||||
}
|
||||
|
||||
public static void addText(String log)
|
||||
{
|
||||
textPaneMain.setText(log);
|
||||
}
|
||||
}
|
90
L2ClientDat/java/com/l2jmobius/actions/MassRecryptor.java
Normal file
90
L2ClientDat/java/com/l2jmobius/actions/MassRecryptor.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.actions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
|
||||
public class MassRecryptor
|
||||
{
|
||||
private static final MassRecryptor _instance = new MassRecryptor();
|
||||
|
||||
public static MassRecryptor getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void recrypt(String chronicle, String path, DatCrypter decCrypter, DatCrypter enCrypter)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Mass recrypt with using " + chronicle + " chronicles by path [" + path + "]", true);
|
||||
File baseDir = new File(path);
|
||||
if (!baseDir.exists())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Directory [" + path + "] does not exists.", true);
|
||||
return;
|
||||
}
|
||||
String recryptDirPath = path + "/" + "!recrypted";
|
||||
File recryptDir = new File(recryptDirPath);
|
||||
if (!recryptDir.exists() && !recryptDir.mkdir())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Cannot create recrypt directory [" + recryptDirPath + "].", true);
|
||||
return;
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (File file : baseDir.listFiles(pathname -> pathname.getName().endsWith(".dat") || pathname.getName().endsWith(".ini") || pathname.getName().endsWith(".htm")))
|
||||
{
|
||||
try
|
||||
{
|
||||
try (FileInputStream fis = new FileInputStream(file);)
|
||||
{
|
||||
if (fis.available() < 28)
|
||||
{
|
||||
L2ClientDat.addLogConsole(file.getName() + " The file is too small.", true);
|
||||
return;
|
||||
}
|
||||
byte[] head = new byte[28];
|
||||
fis.read(head);
|
||||
String header = new String(head, "UTF-16LE");
|
||||
if (!header.startsWith("Lineage2Ver"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + file.getName() + " not encrypted. Skip decrypt.", true);
|
||||
continue;
|
||||
}
|
||||
if (Integer.valueOf(header.substring(11)).intValue() != decCrypter.getCode())
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + file.getName() + " encrypted code: " + header + ". Skip decrypt.", true);
|
||||
continue;
|
||||
}
|
||||
L2ClientDat.addLogConsole("Recrypting [" + file.getName() + "]", true);
|
||||
DatFile dat = new DatFile(file.getAbsolutePath());
|
||||
dat.decrypt(decCrypter);
|
||||
DatFile.encrypt(dat.getBuff().array(), recryptDirPath + "/" + file.getName(), enCrypter);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
L2ClientDat.addLogConsole(file.getName() + " Decrypt failed.", true);
|
||||
}
|
||||
}
|
||||
long diffTime = (System.currentTimeMillis() - startTime) / 1000L;
|
||||
L2ClientDat.addLogConsole("Completed. Elapsed ".concat(String.valueOf(diffTime)).concat(" sec"), true);
|
||||
}
|
||||
}
|
134
L2ClientDat/java/com/l2jmobius/actions/MassTxtPacker.java
Normal file
134
L2ClientDat/java/com/l2jmobius/actions/MassTxtPacker.java
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.actions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.xml.Descriptor;
|
||||
import com.l2jmobius.xml.DescriptorParser;
|
||||
import com.l2jmobius.xml.DescriptorWriter;
|
||||
import com.l2jmobius.xml.exceptions.PackDataException;
|
||||
|
||||
public class MassTxtPacker
|
||||
{
|
||||
private static final MassTxtPacker _instance = new MassTxtPacker();
|
||||
|
||||
public static MassTxtPacker getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void pack(String chronicle, String path, DatCrypter crypter) throws Exception
|
||||
{
|
||||
L2ClientDat.addLogConsole("Mass packer with using " + chronicle + " chronicles by path [" + path + "]", true);
|
||||
File baseDir = new File(path);
|
||||
if (!baseDir.exists())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Directory [" + path + "] does not exists.", true);
|
||||
return;
|
||||
}
|
||||
String packDirPath = path + "/" + "!packed";
|
||||
File packDir = new File(packDirPath);
|
||||
if (!packDir.exists() && !packDir.mkdir())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Cannot create directory [" + packDir + "].", true);
|
||||
return;
|
||||
}
|
||||
File[] fList = baseDir.listFiles(pathname -> crypter.checkFileExtension(pathname.getName()));
|
||||
GameDataName.getInstance().clear();
|
||||
long startTime = System.currentTimeMillis();
|
||||
CountDownLatch doneSignal = new CountDownLatch(fList.length);
|
||||
Semaphore semaphore = new Semaphore(Runtime.getRuntime().availableProcessors());
|
||||
for (File file : fList)
|
||||
{
|
||||
new Thread(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
semaphore.acquire();
|
||||
L2ClientDat.addLogConsole("Packing [" + file.getName() + "]", true);
|
||||
try
|
||||
{
|
||||
byte[] buff = null;
|
||||
String name = file.getName();
|
||||
if (crypter.isUseStructure())
|
||||
{
|
||||
name = name.replace(".txt", ".dat");
|
||||
byte[] array = Files.readAllBytes(file.toPath());
|
||||
String joined = new String(array, 0, array.length, "UTF-8");
|
||||
Descriptor desc = DescriptorParser.getInstance().findDescriptorForFile(chronicle, name);
|
||||
if (desc != null)
|
||||
{
|
||||
buff = DescriptorWriter.parseData(file, crypter, desc, joined);
|
||||
}
|
||||
else
|
||||
{
|
||||
L2ClientDat.addLogConsole("Not found the structure of the file: " + file.getName(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buff = Files.readAllBytes(file.toPath());
|
||||
}
|
||||
String fResult = packDir + "/" + name;
|
||||
if (buff != null)
|
||||
{
|
||||
if (ConfigDebug.ENCRYPT)
|
||||
{
|
||||
DatFile.encrypt(buff, fResult, crypter);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileOutputStream os = new FileOutputStream(fResult, false);
|
||||
os.write(buff);
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (PackDataException e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
doneSignal.countDown();
|
||||
semaphore.release();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
doneSignal.await();
|
||||
GameDataName.getInstance().checkAndUpdate(packDir.getPath(), crypter);
|
||||
long diffTime = (System.currentTimeMillis() - startTime) / 1000L;
|
||||
L2ClientDat.addLogConsole("Completed. Elapsed ".concat(String.valueOf(diffTime)).concat(" sec"), true);
|
||||
}
|
||||
}
|
165
L2ClientDat/java/com/l2jmobius/actions/MassTxtUnpacker.java
Normal file
165
L2ClientDat/java/com/l2jmobius/actions/MassTxtUnpacker.java
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.actions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.xml.Descriptor;
|
||||
import com.l2jmobius.xml.DescriptorParser;
|
||||
import com.l2jmobius.xml.DescriptorReader;
|
||||
|
||||
public class MassTxtUnpacker
|
||||
{
|
||||
private static final MassTxtUnpacker _instance = new MassTxtUnpacker();
|
||||
|
||||
public static MassTxtUnpacker getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void unpack(String chronicle, String path, DatCrypter decCrypter)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Mass unpacker with using " + chronicle + " chronicles by path [" + path + "]", true);
|
||||
File baseDir = new File(path);
|
||||
if (!baseDir.exists())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Directory [" + path + "] does not exists.", true);
|
||||
return;
|
||||
}
|
||||
String unpackDirPath = path + "/" + "!unpacked";
|
||||
File unpackDir = new File(unpackDirPath);
|
||||
if (!unpackDir.exists() && !unpackDir.mkdir())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Cannot create recrypt directory [" + unpackDirPath + "].", true);
|
||||
return;
|
||||
}
|
||||
GameDataName.getInstance().clear();
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (File file : baseDir.listFiles(pathname -> decCrypter.checkFileExtension(pathname.getName())))
|
||||
{
|
||||
try
|
||||
{
|
||||
try (FileInputStream fis = new FileInputStream(file);)
|
||||
{
|
||||
String name;
|
||||
String res;
|
||||
String charset;
|
||||
if (fis.available() < 28)
|
||||
{
|
||||
L2ClientDat.addLogConsole(file.getName() + " The file is too small.", true);
|
||||
continue;
|
||||
}
|
||||
byte[] head = new byte[28];
|
||||
fis.read(head);
|
||||
fis.close();
|
||||
String header = new String(head, "UTF-16LE");
|
||||
if (!header.startsWith("Lineage2Ver"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + file.getName() + " not encrypted. Skip decrypt.", true);
|
||||
continue;
|
||||
}
|
||||
if (Integer.valueOf(header.substring(11)).intValue() != decCrypter.getCode())
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + file.getName() + " encrypted code: " + header + ". Skip decrypt.", true);
|
||||
continue;
|
||||
}
|
||||
L2ClientDat.addLogConsole("Unpacking [" + file.getName() + "]", true);
|
||||
DatFile dat = new DatFile(file.getAbsolutePath());
|
||||
dat.decrypt(decCrypter);
|
||||
DebugUtil.save(dat.getBuff(), file);
|
||||
res = null;
|
||||
charset = "UTF-8";
|
||||
if (decCrypter.isUseStructure() && file.getName().endsWith(".dat"))
|
||||
{
|
||||
Descriptor desc = DescriptorParser.getInstance().findDescriptorForFile(chronicle, file.getName());
|
||||
try
|
||||
{
|
||||
res = DescriptorReader.getInstance().parseData(file, decCrypter, desc, dat.getBuff());
|
||||
}
|
||||
catch (Exception e23)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Cannot parse [" + file.getName() + "]", true);
|
||||
}
|
||||
name = file.getName().replace(".dat", ".txt");
|
||||
}
|
||||
else
|
||||
{
|
||||
name = file.getName();
|
||||
if (file.getName().endsWith(".unr"))
|
||||
{
|
||||
name = "dec-" + name;
|
||||
}
|
||||
if (file.getName().endsWith(".htm"))
|
||||
{
|
||||
charset = "UTF-16";
|
||||
}
|
||||
try
|
||||
{
|
||||
try (FileOutputStream fos = new FileOutputStream(unpackDirPath + "/" + name);)
|
||||
{
|
||||
fos.write(dat.getBuff().array());
|
||||
}
|
||||
catch (Throwable throwable)
|
||||
{
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException e3)
|
||||
{
|
||||
e3.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (res == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
try (PrintWriter fos = new PrintWriter(new OutputStreamWriter(new FileOutputStream(unpackDirPath + "/" + name), charset));)
|
||||
{
|
||||
fos.write(res);
|
||||
}
|
||||
catch (Throwable throwable)
|
||||
{
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
catch (Exception e4)
|
||||
{
|
||||
DebugUtil.getLogger().error("Cannot write file.", e4);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(file.getName() + " Decrypt failed.", e);
|
||||
}
|
||||
}
|
||||
long diffTime = (System.currentTimeMillis() - startTime) / 1000L;
|
||||
L2ClientDat.addLogConsole("Completed. Elapsed ".concat(String.valueOf(diffTime)).concat(" sec"), true);
|
||||
}
|
||||
}
|
143
L2ClientDat/java/com/l2jmobius/actions/OpenDat.java
Normal file
143
L2ClientDat/java/com/l2jmobius/actions/OpenDat.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.actions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.xml.Descriptor;
|
||||
import com.l2jmobius.xml.DescriptorParser;
|
||||
import com.l2jmobius.xml.DescriptorReader;
|
||||
|
||||
public class OpenDat
|
||||
{
|
||||
public static void start(String dir, File path, String name, DatCrypter crypter) throws Exception
|
||||
{
|
||||
ByteBuffer buffer;
|
||||
boolean crypt = true;
|
||||
if (!path.exists())
|
||||
{
|
||||
L2ClientDat.addLogConsole("File does not exist.", true);
|
||||
return;
|
||||
}
|
||||
if (!path.canRead())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Unable to read file.", true);
|
||||
return;
|
||||
}
|
||||
FileInputStream fis = new FileInputStream(path);
|
||||
if (fis.available() < 28)
|
||||
{
|
||||
L2ClientDat.addLogConsole("The file is too small.", true);
|
||||
fis.close();
|
||||
return;
|
||||
}
|
||||
byte[] head = new byte[28];
|
||||
fis.read(head);
|
||||
String header = new String(head, "UTF-16LE");
|
||||
if (!header.startsWith("Lineage2Ver"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + name + " not encrypted. Skip decrypt.", true);
|
||||
crypt = false;
|
||||
}
|
||||
fis.close();
|
||||
buffer = null;
|
||||
if (crypt)
|
||||
{
|
||||
L2ClientDat.addLogConsole("File " + name + " encrypted. " + header + " decrypt ...", true);
|
||||
try
|
||||
{
|
||||
DatFile dat = new DatFile(path.getPath());
|
||||
dat.decrypt(crypter);
|
||||
buffer = dat.getBuff();
|
||||
if (buffer == null)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Error decrypt file. Empty buffer.", true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Error decrypt file.", true);
|
||||
return;
|
||||
}
|
||||
DebugUtil.save(buffer, path);
|
||||
L2ClientDat.addLogConsole("Decrypt successfully.", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
try (FileInputStream fIn = new FileInputStream(path);)
|
||||
{
|
||||
FileChannel fChan = fIn.getChannel();
|
||||
ByteBuffer mBuf = ByteBuffer.allocate((int) fChan.size());
|
||||
fChan.read(mBuf);
|
||||
buffer = mBuf;
|
||||
fChan.close();
|
||||
fIn.close();
|
||||
}
|
||||
}
|
||||
catch (IOException exc)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Error reading.", true);
|
||||
}
|
||||
}
|
||||
if (name.contains(".ini") || name.contains(".txt"))
|
||||
{
|
||||
if ((buffer != null) && buffer.hasArray())
|
||||
{
|
||||
L2ClientDat.addText(new String(buffer.array(), 0, buffer.array().length, "UTF-8"));
|
||||
}
|
||||
}
|
||||
else if (name.contains(".htm"))
|
||||
{
|
||||
if ((buffer != null) && buffer.hasArray())
|
||||
{
|
||||
L2ClientDat.addText(new String(buffer.array(), 0, buffer.array().length, "UTF-16"));
|
||||
}
|
||||
}
|
||||
else if (crypter.isUseStructure())
|
||||
{
|
||||
L2ClientDat.addLogConsole("Read the file structure ...", true);
|
||||
String data = null;
|
||||
Descriptor desc = DescriptorParser.getInstance().findDescriptorForFile(dir, name);
|
||||
if ((desc != null) && (buffer != null))
|
||||
{
|
||||
buffer.position(0);
|
||||
DebugUtil.debug("Buffer size: " + buffer.limit());
|
||||
GameDataName.getInstance().clear();
|
||||
data = DescriptorReader.getInstance().parseData(path, crypter, desc, buffer);
|
||||
}
|
||||
if (data == null)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Structure is not found in the directory: " + dir + " file: " + name, true);
|
||||
return;
|
||||
}
|
||||
L2ClientDat.addText(data);
|
||||
}
|
||||
L2ClientDat.addLogConsole("Completed.", true);
|
||||
}
|
||||
}
|
140
L2ClientDat/java/com/l2jmobius/clientcryptor/DatFile.java
Normal file
140
L2ClientDat/java/com/l2jmobius/clientcryptor/DatFile.java
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
|
||||
public class DatFile extends File
|
||||
{
|
||||
private ByteBuffer _buff;
|
||||
|
||||
public DatFile(String pathname)
|
||||
{
|
||||
super(pathname);
|
||||
}
|
||||
|
||||
public ByteBuffer getBuff()
|
||||
{
|
||||
return _buff;
|
||||
}
|
||||
|
||||
public void decrypt(DatCrypter crypter) throws IOException
|
||||
{
|
||||
loadInfo(crypter);
|
||||
try
|
||||
{
|
||||
try (FileInputStream fis = new FileInputStream(this);)
|
||||
{
|
||||
crypter.unlock();
|
||||
crypter.aquire();
|
||||
fis.skip(28L);
|
||||
byte[] buff = new byte[crypter.getChunkSize(fis.available())];
|
||||
for (int len = fis.available() - crypter.getSkipSize(); len > 0; len -= fis.read(buff))
|
||||
{
|
||||
crypter.update(buff);
|
||||
if (!crypter.isLock())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (crypter.isLock())
|
||||
{
|
||||
_buff = null;
|
||||
return;
|
||||
}
|
||||
_buff = crypter.decryptResult();
|
||||
crypter.release();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void encrypt(byte[] buff, String file, DatCrypter crypter) throws IOException
|
||||
{
|
||||
crypter.unlock();
|
||||
crypter.aquire();
|
||||
FileOutputStream os = new FileOutputStream(file, false);
|
||||
String header = "Lineage2Ver" + crypter.getCode();
|
||||
os.write(header.getBytes("UTF-16LE"));
|
||||
crypter.update(buff);
|
||||
byte[] res = crypter.encryptResult().array();
|
||||
os.write(res);
|
||||
if (ConfigDebug.DAT_ADD_END_BYTES)
|
||||
{
|
||||
byte[] endBytes = new byte[20];
|
||||
endBytes[19] = 100;
|
||||
os.write(endBytes);
|
||||
}
|
||||
os.close();
|
||||
crypter.release();
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
private void loadInfo(DatCrypter crypter) throws IOException
|
||||
{
|
||||
if (!exists() || !canRead())
|
||||
{
|
||||
throw new IOException("Can not read the dat file");
|
||||
}
|
||||
FileInputStream fis = new FileInputStream(this);
|
||||
if (fis.available() < 28)
|
||||
{
|
||||
throw new IOException("Can not read the dat file : too small");
|
||||
}
|
||||
byte[] head = new byte[28];
|
||||
fis.read(head);
|
||||
String header = new String(head, "UTF-16LE");
|
||||
if (!header.startsWith("Lineage2Ver"))
|
||||
{
|
||||
throw new IOException("Can not read the dat file : wrong header");
|
||||
}
|
||||
if (header.endsWith("111") || header.endsWith("120"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (header.endsWith("211") || header.endsWith("212"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (header.endsWith("311"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (header.endsWith("411") || header.endsWith("412") || header.endsWith("413") || header.endsWith("414"))
|
||||
{
|
||||
if (fis.available() < 20)
|
||||
{
|
||||
throw new IOException("Can not read the dat file : too small");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Can not read the dat file : unknown header : '" + header + "'");
|
||||
}
|
||||
fis.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor.crypt;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BlowFishDatCrypter extends DatCrypter
|
||||
{
|
||||
private boolean encrypt = false;
|
||||
private final BlowfishEngine blowfish = new BlowfishEngine();
|
||||
|
||||
public BlowFishDatCrypter(int code, String key, boolean deCrypt)
|
||||
{
|
||||
super(code);
|
||||
encrypt = !deCrypt;
|
||||
blowfish.init(encrypt, key.getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer decryptResult()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer encryptResult()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] b)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkSize(int available)
|
||||
{
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkipSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypt()
|
||||
{
|
||||
return encrypt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock()
|
||||
{
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor.crypt;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
|
||||
public class DESDatCrypter extends DatCrypter
|
||||
{
|
||||
private ByteArrayOutputStream _result;
|
||||
private final boolean encrypt;
|
||||
private final Cipher _cipher;
|
||||
|
||||
public DESDatCrypter(int code, String sKey, boolean deCrypt) throws Exception
|
||||
{
|
||||
super(code);
|
||||
encrypt = !deCrypt;
|
||||
byte[] key = sKey.getBytes();
|
||||
byte[] keyXor = new byte[key.length];
|
||||
for (int i = 0; i < key.length; ++i)
|
||||
{
|
||||
byte[] arrby = keyXor;
|
||||
int n = i % 8;
|
||||
arrby[n] = (byte) (arrby[n] ^ key[i]);
|
||||
}
|
||||
DESKeySpec dks = new DESKeySpec(keyXor);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
|
||||
SecretKey desKey = skf.generateSecret(dks);
|
||||
_cipher = Cipher.getInstance("DES/ECB/NoPadding");
|
||||
_cipher.init(deCrypt ? 2 : 1, desKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer decryptResult()
|
||||
{
|
||||
return ByteBuffer.wrap(_result.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer encryptResult()
|
||||
{
|
||||
return ByteBuffer.wrap(_result.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] bArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!encrypt)
|
||||
{
|
||||
int size;
|
||||
_result = new ByteArrayOutputStream(bArray.length);
|
||||
byte[] bytes = new byte[8];
|
||||
for (int position = 0; position < bArray.length; position += size)
|
||||
{
|
||||
size = Math.min(8, bArray.length - position);
|
||||
System.arraycopy(bArray, position, bytes, 0, size);
|
||||
_result.write(size == 8 ? _cipher.doFinal(bytes) : bytes, 0, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkSize(int available)
|
||||
{
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkipSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypt()
|
||||
{
|
||||
return encrypt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void aquire()
|
||||
{
|
||||
super.aquire();
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor.crypt;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public abstract class DatCrypter
|
||||
{
|
||||
private final ReentrantLock _lock = new ReentrantLock(true);
|
||||
private final int code;
|
||||
private boolean useStructure;
|
||||
private final List<String> fileEndNames = new ArrayList<>();
|
||||
|
||||
public DatCrypter(int code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public abstract void update(byte[] var1);
|
||||
|
||||
public abstract ByteBuffer decryptResult();
|
||||
|
||||
public abstract ByteBuffer encryptResult();
|
||||
|
||||
public abstract int getChunkSize(int var1);
|
||||
|
||||
public abstract int getSkipSize();
|
||||
|
||||
public abstract boolean isLock();
|
||||
|
||||
public boolean checkAquired()
|
||||
{
|
||||
return _lock.isHeldByCurrentThread();
|
||||
}
|
||||
|
||||
public void aquire()
|
||||
{
|
||||
_lock.lock();
|
||||
}
|
||||
|
||||
public void release()
|
||||
{
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
public abstract boolean isEncrypt();
|
||||
|
||||
public abstract void unlock();
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public void addFileExtension(String n)
|
||||
{
|
||||
fileEndNames.addAll(Arrays.asList(n.split(";")));
|
||||
}
|
||||
|
||||
public boolean checkFileExtension(String n)
|
||||
{
|
||||
return n.contains(".") && fileEndNames.contains(n.split("\\.")[1]);
|
||||
}
|
||||
|
||||
public boolean isUseStructure()
|
||||
{
|
||||
return useStructure;
|
||||
}
|
||||
|
||||
public void setUseStructure(boolean useStructure)
|
||||
{
|
||||
this.useStructure = useStructure;
|
||||
}
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor.crypt;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.util.Util;
|
||||
|
||||
public class RSADatCrypter extends DatCrypter
|
||||
{
|
||||
private Cipher _cipher;
|
||||
private ByteArrayOutputStream _result;
|
||||
private boolean encrypt = false;
|
||||
private boolean _errorLock = false;
|
||||
|
||||
public RSADatCrypter(int code, String modulus, String exp, boolean deCrypt)
|
||||
{
|
||||
super(code);
|
||||
try
|
||||
{
|
||||
_cipher = Cipher.getInstance("RSA/ECB/nopadding");
|
||||
if (deCrypt)
|
||||
{
|
||||
RSAPublicKeySpec keyspec = new RSAPublicKeySpec(new BigInteger(modulus, 16), new BigInteger(exp, 16));
|
||||
RSAPublicKey rsaKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(keyspec);
|
||||
_cipher.init(2, rsaKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
encrypt = true;
|
||||
RSAPrivateKeySpec keyspec = new RSAPrivateKeySpec(new BigInteger(modulus, 16), new BigInteger(exp, 16));
|
||||
RSAPrivateKey rsaKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(keyspec);
|
||||
_cipher.init(1, rsaKey);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer decryptResult()
|
||||
{
|
||||
if (!checkAquired())
|
||||
{
|
||||
throw new IllegalStateException("Dont even think about using a DatCrypter that you didnt aquired");
|
||||
}
|
||||
byte[] compressed = _result.toByteArray();
|
||||
int inflatedSize = compressed[0] & 255;
|
||||
inflatedSize += (compressed[1] << 8) & 65280;
|
||||
inflatedSize += (compressed[2] << 16) & 16711680;
|
||||
inflatedSize += (compressed[3] << 24) & -16777216;
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(compressed, 4, compressed.length - 4);
|
||||
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128);
|
||||
byte[] inflatedResult = new byte[128];
|
||||
try
|
||||
{
|
||||
int len;
|
||||
while ((len = iis.read(inflatedResult)) > 0)
|
||||
{
|
||||
baos.write(inflatedResult, 0, len);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (baos.size() != inflatedSize)
|
||||
{
|
||||
DebugUtil.getLogger().error("[RSADatCrypter] Hum inflated result doesnt have the expected length..(" + baos.size() + "!=" + inflatedSize + ")");
|
||||
}
|
||||
return ByteBuffer.wrap(baos.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer encryptResult()
|
||||
{
|
||||
if (!checkAquired())
|
||||
{
|
||||
throw new IllegalStateException("Dont even think about using a DatCrypter that you didnt aquired");
|
||||
}
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
try
|
||||
{
|
||||
int len;
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(_result.toByteArray());
|
||||
byte[] buffer = new byte[124];
|
||||
byte[] block = new byte[128];
|
||||
while ((len = input.read(buffer)) > 0)
|
||||
{
|
||||
Arrays.fill(block, (byte) 0);
|
||||
block[0] = (byte) ((len >> 24) & 255);
|
||||
block[1] = (byte) ((len >> 16) & 255);
|
||||
block[2] = (byte) ((len >> 8) & 255);
|
||||
block[3] = (byte) (len & 255);
|
||||
System.arraycopy(buffer, 0, block, 128 - len - ((124 - len) % 4), len);
|
||||
result.write(_cipher.doFinal(block));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ByteBuffer.wrap(result.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] b)
|
||||
{
|
||||
if (!checkAquired())
|
||||
{
|
||||
throw new IllegalStateException("Dont even think about using a DatCrypter that you didnt aquired");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (!encrypt)
|
||||
{
|
||||
byte[] chunk = _cipher.doFinal(b);
|
||||
int size = chunk[3];
|
||||
size += (chunk[2] << 8) & 65280;
|
||||
size += (chunk[1] << 16) & 16711680;
|
||||
int pad = (-size & 1) + (-(size += (chunk[0] << 24) & -16777216) & 2);
|
||||
DebugUtil.debug("Size:" + size + " pad:" + pad);
|
||||
if (size > 128)
|
||||
{
|
||||
_errorLock = true;
|
||||
return;
|
||||
}
|
||||
_result.write(chunk, 128 - size - pad, size);
|
||||
DebugUtil.debug("--- BLOCK:\n" + Util.printData(chunk) + "-----");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream s = new ByteArrayOutputStream(b.length);
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(s, new Deflater());
|
||||
dos.write(b);
|
||||
dos.finish();
|
||||
dos.close();
|
||||
int l = b.length;
|
||||
_result = new ByteArrayOutputStream(10 + s.toByteArray().length);
|
||||
_result.write(l & 255);
|
||||
_result.write((l & 65280) >> 8);
|
||||
_result.write((l & 16711680) >> 16);
|
||||
_result.write((l & -16777216) >> 24);
|
||||
_result.write(s.toByteArray());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
_errorLock = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void aquire()
|
||||
{
|
||||
super.aquire();
|
||||
_result = new ByteArrayOutputStream(128);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypt()
|
||||
{
|
||||
return encrypt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkSize(int available)
|
||||
{
|
||||
return 128;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkipSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLock()
|
||||
{
|
||||
return _errorLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock()
|
||||
{
|
||||
_errorLock = false;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.clientcryptor.crypt;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class XorDatCrypter extends DatCrypter
|
||||
{
|
||||
private ByteArrayOutputStream _result;
|
||||
private final boolean encrypt;
|
||||
private final int xorKey;
|
||||
|
||||
public XorDatCrypter(int code, int key, boolean deCrypt)
|
||||
{
|
||||
super(code);
|
||||
encrypt = !deCrypt;
|
||||
xorKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer decryptResult()
|
||||
{
|
||||
return ByteBuffer.wrap(_result.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer encryptResult()
|
||||
{
|
||||
return ByteBuffer.wrap(_result.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] bArray)
|
||||
{
|
||||
for (byte b : bArray)
|
||||
{
|
||||
_result.write(b ^ xorKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkSize(int available)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkipSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypt()
|
||||
{
|
||||
return encrypt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void aquire()
|
||||
{
|
||||
super.aquire();
|
||||
_result = new ByteArrayOutputStream(128);
|
||||
}
|
||||
}
|
52
L2ClientDat/java/com/l2jmobius/config/ConfigDebug.java
Normal file
52
L2ClientDat/java/com/l2jmobius/config/ConfigDebug.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
|
||||
import jfork.nproperty.Cfg;
|
||||
import jfork.nproperty.CfgIgnore;
|
||||
import jfork.nproperty.ConfigParser;
|
||||
|
||||
@Cfg
|
||||
public class ConfigDebug extends ConfigParser
|
||||
{
|
||||
@CfgIgnore
|
||||
private static final ConfigDebug _instance = new ConfigDebug();
|
||||
public static boolean DAT_ADD_END_BYTES = true;
|
||||
public static boolean DAT_DEBUG_MSG = false;
|
||||
public static boolean DAT_DEBUG_POS = false;
|
||||
public static int DAT_DEBUG_POS_LIMIT = 100000;
|
||||
public static boolean DAT_REPLACEMENT_NAMES = true;
|
||||
public static boolean ENCRYPT = true;
|
||||
public static boolean SAVE_DECODE = false;
|
||||
|
||||
public static void load()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigParser.parse((_instance), "./config/config_debug.ini");
|
||||
}
|
||||
catch (IOException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
||||
{
|
||||
DebugUtil.getLogger().error("Failed to load configuration file.", e);
|
||||
}
|
||||
}
|
||||
}
|
78
L2ClientDat/java/com/l2jmobius/config/ConfigWindow.java
Normal file
78
L2ClientDat/java/com/l2jmobius/config/ConfigWindow.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.config;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
|
||||
import jfork.nproperty.Cfg;
|
||||
import jfork.nproperty.CfgIgnore;
|
||||
import jfork.nproperty.ConfigParser;
|
||||
|
||||
@Cfg
|
||||
public class ConfigWindow extends ConfigParser
|
||||
{
|
||||
@CfgIgnore
|
||||
private static final ConfigWindow _instance = new ConfigWindow();
|
||||
@CfgIgnore
|
||||
private static final String PATH = "./config/config_window.ini";
|
||||
public static String FILE_OPEN_CURRENT_DIRECTORY_UNPACK = ".";
|
||||
public static String FILE_OPEN_CURRENT_DIRECTORY_PACK = ".";
|
||||
public static String FILE_OPEN_CURRENT_DIRECTORY = ".";
|
||||
public static String FILE_SAVE_CURRENT_DIRECTORY = ".";
|
||||
public static String CURRENT_CHRONICLE = "";
|
||||
public static int WINDOW_HEIGHT = 600;
|
||||
public static int WINDOW_WIDTH = 800;
|
||||
public static String CURRENT_ENCRYPT = ".";
|
||||
public static String CURRENT_DECRYPT = ".";
|
||||
public static String LAST_FILE_SELECTED = ".";
|
||||
|
||||
public static void load()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigParser.parse((_instance), PATH);
|
||||
}
|
||||
catch (IOException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e)
|
||||
{
|
||||
DebugUtil.getLogger().error("Failed to load configuration file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void save(String key, String var)
|
||||
{
|
||||
try
|
||||
{
|
||||
Properties props = new Properties();
|
||||
props.load(new FileInputStream(PATH));
|
||||
props.setProperty(key, var);
|
||||
FileOutputStream output = new FileOutputStream(PATH);
|
||||
props.store(output, "Saved settings");
|
||||
output.close();
|
||||
ConfigWindow.load();
|
||||
}
|
||||
catch (Exception props)
|
||||
{
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
}
|
238
L2ClientDat/java/com/l2jmobius/data/GameDataName.java
Normal file
238
L2ClientDat/java/com/l2jmobius/data/GameDataName.java
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.data;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.DatFile;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.util.ByteReader;
|
||||
import com.l2jmobius.util.ByteWriter;
|
||||
import com.l2jmobius.util.Util;
|
||||
import com.l2jmobius.xml.ParamNode;
|
||||
|
||||
public class GameDataName
|
||||
{
|
||||
private static final byte[] endFileBytes = new byte[]
|
||||
{
|
||||
12,
|
||||
83,
|
||||
97,
|
||||
102,
|
||||
101,
|
||||
80,
|
||||
97,
|
||||
99,
|
||||
107,
|
||||
97,
|
||||
103,
|
||||
101,
|
||||
0
|
||||
};
|
||||
private final Map<Integer, String> names = new HashMap<>();
|
||||
private final Map<String, Integer> nameHash = new HashMap<>();
|
||||
private final Map<String, Integer> nameLowHash = new HashMap<>();
|
||||
|
||||
private void load(File currentFile, DatCrypter decCrypter) throws Exception
|
||||
{
|
||||
names.clear();
|
||||
nameHash.clear();
|
||||
nameLowHash.clear();
|
||||
if (decCrypter.isEncrypt())
|
||||
{
|
||||
File file = new File(currentFile.getParent(), "L2GameDataName.txt");
|
||||
if (file.exists())
|
||||
{
|
||||
List<String> list = Files.readAllLines(file.toPath());
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
String str = list.get(i);
|
||||
Map<String, String> map = Util.stringToMap(str);
|
||||
String name = map.get("name");
|
||||
name = name.substring(1, name.length() - 1);
|
||||
names.put(i, name);
|
||||
nameHash.put(name, i);
|
||||
nameLowHash.put(name.toLowerCase(), i);
|
||||
}
|
||||
L2ClientDat.addLogConsole("GameDataName: Load " + names.size() + " count.", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = new File(currentFile.getParent(), "L2GameDataName.dat");
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
if (fis.available() < 28)
|
||||
{
|
||||
L2ClientDat.addLogConsole(file.getName() + " The file is too small.", true);
|
||||
fis.close();
|
||||
return;
|
||||
}
|
||||
byte[] head = new byte[28];
|
||||
fis.read(head);
|
||||
fis.close();
|
||||
String header = new String(head, "UTF-16LE");
|
||||
if (!header.startsWith("Lineage2Ver"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: File " + file.getName() + " not encrypted. Skip decrypt.", true);
|
||||
return;
|
||||
}
|
||||
if (Integer.valueOf(header.substring(11)).intValue() != decCrypter.getCode())
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: File " + file.getName() + " encrypted code: " + header + ". Skip decrypt.", true);
|
||||
return;
|
||||
}
|
||||
L2ClientDat.addLogConsole("Unpacking [" + file.getName() + "]", true);
|
||||
DatFile dat = new DatFile(file.getAbsolutePath());
|
||||
dat.decrypt(decCrypter);
|
||||
ByteBuffer buff = dat.getBuff();
|
||||
int size = ByteReader.readUInt(buff);
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
String name = ByteReader.readUtfString(buff, false);
|
||||
if (name.contains("[") || name.contains("]"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: Error index: " + i + " string: " + name, true);
|
||||
}
|
||||
names.put(i, name);
|
||||
nameHash.put(name, i);
|
||||
nameLowHash.put(name.toLowerCase(), i);
|
||||
}
|
||||
L2ClientDat.addLogConsole("GameDataName: Load " + names.size() + " count.", true);
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(File currentFile, DatCrypter crypter, int index) throws Exception
|
||||
{
|
||||
String val;
|
||||
if (names.isEmpty())
|
||||
{
|
||||
load(currentFile, crypter);
|
||||
}
|
||||
if (!names.containsKey(index))
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: Not found index: " + index, true);
|
||||
}
|
||||
if ((val = names.getOrDefault(index, String.valueOf(index))).isEmpty())
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: String name Empty!!! file: " + currentFile.getName(), true);
|
||||
}
|
||||
return "[" + val + "]";
|
||||
}
|
||||
|
||||
public synchronized int getId(File currentFile, DatCrypter crypter, ParamNode node, String str) throws Exception
|
||||
{
|
||||
String low;
|
||||
if (!str.startsWith("[") || !str.endsWith("]"))
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: String name not brackets!!! file: " + currentFile.getName() + " str: " + str + " node: " + node, true);
|
||||
}
|
||||
if ((str = str.substring(1, str.length() - 1)).isEmpty())
|
||||
{
|
||||
L2ClientDat.addLogConsole("GameDataName: String name Empty!!! file: " + currentFile.getName() + " node: " + node, true);
|
||||
return -1;
|
||||
}
|
||||
if (nameLowHash.isEmpty())
|
||||
{
|
||||
load(currentFile, crypter);
|
||||
}
|
||||
if (nameLowHash.containsKey(low = str.toLowerCase()))
|
||||
{
|
||||
return nameLowHash.get(low);
|
||||
}
|
||||
int newIndex = nameLowHash.size();
|
||||
nameLowHash.put(low, newIndex);
|
||||
nameHash.put(str, nameHash.size());
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
public void checkAndUpdate(String currentDir, DatCrypter crypter) throws Exception
|
||||
{
|
||||
if (!nameHash.isEmpty())
|
||||
{
|
||||
HashSet<String> setList = new HashSet<>();
|
||||
TreeMap<Integer, String> sortedMap = new TreeMap<>();
|
||||
for (String key : nameHash.keySet())
|
||||
{
|
||||
sortedMap.put(nameHash.get(key), key);
|
||||
if (setList.add(key.toLowerCase()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
L2ClientDat.addLogConsole("GameDataName: name " + key + " conflicted.", true);
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
baos.write((byte[]) ByteWriter.writeInt(sortedMap.size()).array());
|
||||
for (String key : sortedMap.values())
|
||||
{
|
||||
baos.write((byte[]) ByteWriter.writeUtfString(key, false).array());
|
||||
}
|
||||
byte[] bytes = baos.toByteArray();
|
||||
byte[] resultBytes = new byte[bytes.length + endFileBytes.length];
|
||||
System.arraycopy(bytes, 0, resultBytes, 0, bytes.length);
|
||||
System.arraycopy(endFileBytes, 0, resultBytes, bytes.length, endFileBytes.length);
|
||||
String file = currentDir + "/L2GameDataName.dat";
|
||||
if (ConfigDebug.ENCRYPT)
|
||||
{
|
||||
DatFile.encrypt(resultBytes, file, crypter);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileOutputStream os = new FileOutputStream(file, false);
|
||||
os.write(resultBytes);
|
||||
os.close();
|
||||
}
|
||||
L2ClientDat.addLogConsole("GameDataName: packed " + sortedMap.size() + " count.", true);
|
||||
names.clear();
|
||||
nameHash.clear();
|
||||
nameLowHash.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
names.clear();
|
||||
nameHash.clear();
|
||||
nameLowHash.clear();
|
||||
}
|
||||
|
||||
public static GameDataName getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
static final GameDataName _instance = new GameDataName();
|
||||
|
||||
private SingletonHolder()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
299
L2ClientDat/java/com/l2jmobius/forms/JPopupTextArea.java
Normal file
299
L2ClientDat/java/com/l2jmobius/forms/JPopupTextArea.java
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.forms;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
public class JPopupTextArea extends JTextArea
|
||||
{
|
||||
static final String COPY = "Copy (Ctrl + C)";
|
||||
static final String CUT = "Cut (Ctrl + X)";
|
||||
static final String PASTE = "Paste (Ctrl + V)";
|
||||
static final String DELETE = "Delete";
|
||||
static final String SELECTALL = "Select all (Ctrl + A)";
|
||||
static final String LINE = "Line (Ctrl + G)";
|
||||
static final String FIND = "Find (Ctrl + F)";
|
||||
Vector<Integer> lineLength = new Vector<>();
|
||||
|
||||
public JPopupTextArea()
|
||||
{
|
||||
addPopupMenu();
|
||||
}
|
||||
|
||||
private void addPopupMenu()
|
||||
{
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem copyItem = new JMenuItem();
|
||||
copyItem.setAction(getActionMap().get("copy-to-clipboard"));
|
||||
copyItem.setText(COPY);
|
||||
JMenuItem cutItem = new JMenuItem();
|
||||
cutItem.setAction(getActionMap().get("cut-to-clipboard"));
|
||||
cutItem.setText(CUT);
|
||||
JMenuItem pasteItem = new JMenuItem();
|
||||
pasteItem.setAction(getActionMap().get("paste-from-clipboard"));
|
||||
pasteItem.setText(PASTE);
|
||||
JMenuItem deleteItem = new JMenuItem();
|
||||
deleteItem.setAction(getActionMap().get("delete-previous"));
|
||||
deleteItem.setText(DELETE);
|
||||
JMenuItem selectAllItem = new JMenuItem();
|
||||
selectAllItem.setAction(getActionMap().get("select-all"));
|
||||
selectAllItem.setText(SELECTALL);
|
||||
JMenuItem selectLine = new JMenuItem();
|
||||
selectLine.addActionListener(e -> goToLine());
|
||||
selectLine.setText(LINE);
|
||||
JMenuItem selectFind = new JMenuItem();
|
||||
selectFind.addActionListener(e -> searchString());
|
||||
selectFind.setText(FIND);
|
||||
menu.add(copyItem);
|
||||
menu.add(cutItem);
|
||||
menu.add(pasteItem);
|
||||
menu.add(deleteItem);
|
||||
menu.add(new JSeparator());
|
||||
menu.add(selectAllItem);
|
||||
menu.add(selectLine);
|
||||
menu.add(selectFind);
|
||||
this.add(menu);
|
||||
addMouseListener(new PopupTriggerMouseListener(menu, this));
|
||||
addKeyListener(new KeyListen());
|
||||
}
|
||||
|
||||
void goToLine()
|
||||
{
|
||||
String lineno;
|
||||
boolean fnd;
|
||||
int no = 0;
|
||||
do
|
||||
{
|
||||
block8:
|
||||
{
|
||||
fnd = true;
|
||||
lineno = JOptionPane.showInputDialog("Line number:");
|
||||
try
|
||||
{
|
||||
no = Integer.parseInt(lineno);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
if (lineno == null)
|
||||
{
|
||||
break block8;
|
||||
}
|
||||
JOptionPane.showMessageDialog(new Frame(), "Enter a valid line number", "Error", 0);
|
||||
fnd = false;
|
||||
}
|
||||
}
|
||||
if ((no > 0) || (lineno == null))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
JOptionPane.showMessageDialog(new Frame(), "Enter a valid line number", "Error", 0);
|
||||
fnd = false;
|
||||
}
|
||||
while (!fnd);
|
||||
if (lineno != null)
|
||||
{
|
||||
getLinePosition();
|
||||
if ((no - 1) >= lineLength.size())
|
||||
{
|
||||
JOptionPane.showMessageDialog(new Frame(), "Line number does not exist", "Error", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
this.requestFocus();
|
||||
setCaretPosition(lineLength.elementAt(no - 1));
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
JOptionPane.showMessageDialog(new Frame(), "Bad position", "Error", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void searchString()
|
||||
{
|
||||
String lineno = JOptionPane.showInputDialog("Search string: ");
|
||||
if ((lineno == null) || lineno.isEmpty())
|
||||
{
|
||||
JOptionPane.showMessageDialog(new Frame(), "Enter a empty string", "Error", 0);
|
||||
return;
|
||||
}
|
||||
if (!lineno.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
this.requestFocus();
|
||||
String editorText = this.getText();
|
||||
String searchValue = lineno;
|
||||
int start = editorText.indexOf(searchValue, getSelectionEnd());
|
||||
if (start != -1)
|
||||
{
|
||||
setCaretPosition(start);
|
||||
moveCaretPosition(start + searchValue.length());
|
||||
getCaret().setSelectionVisible(true);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
JOptionPane.showMessageDialog(new Frame(), "Bad position", "Error", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getLinePosition()
|
||||
{
|
||||
lineLength = new Vector<>();
|
||||
String txt = this.getText();
|
||||
int width = getWidth();
|
||||
StringTokenizer st = new StringTokenizer(txt, "\n ", true);
|
||||
String str = " ";
|
||||
int len = 0;
|
||||
lineLength.addElement(new Integer(0));
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String token = st.nextToken();
|
||||
int w = getGraphics().getFontMetrics(getGraphics().getFont()).stringWidth(str + token);
|
||||
if ((w > width) || (token.charAt(0) == '\n'))
|
||||
{
|
||||
len += str.length();
|
||||
if (token.charAt(0) == '\n')
|
||||
{
|
||||
lineLength.addElement(new Integer(len));
|
||||
}
|
||||
else
|
||||
{
|
||||
lineLength.addElement(new Integer(len - 1));
|
||||
}
|
||||
str = token;
|
||||
continue;
|
||||
}
|
||||
str = str + token;
|
||||
}
|
||||
}
|
||||
|
||||
private class KeyListen implements KeyListener
|
||||
{
|
||||
private boolean controlDown;
|
||||
private boolean gDown;
|
||||
private boolean fDown;
|
||||
|
||||
KeyListen()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == 17)
|
||||
{
|
||||
controlDown = true;
|
||||
}
|
||||
else if (e.getKeyCode() == 71)
|
||||
{
|
||||
gDown = true;
|
||||
}
|
||||
else if (e.getKeyCode() == 70)
|
||||
{
|
||||
fDown = true;
|
||||
}
|
||||
if (controlDown)
|
||||
{
|
||||
if (gDown)
|
||||
{
|
||||
controlDown = false;
|
||||
gDown = false;
|
||||
goToLine();
|
||||
}
|
||||
else if (fDown)
|
||||
{
|
||||
controlDown = false;
|
||||
fDown = false;
|
||||
searchString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == 17)
|
||||
{
|
||||
controlDown = false;
|
||||
}
|
||||
else if (e.getKeyCode() == 71)
|
||||
{
|
||||
gDown = false;
|
||||
}
|
||||
else if (e.getKeyCode() == 70)
|
||||
{
|
||||
fDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class PopupTriggerMouseListener extends MouseAdapter
|
||||
{
|
||||
private final JPopupMenu popup;
|
||||
private final JComponent component;
|
||||
|
||||
public PopupTriggerMouseListener(JPopupMenu popup, JComponent component)
|
||||
{
|
||||
this.popup = popup;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
private void showMenuIfPopupTrigger(MouseEvent e)
|
||||
{
|
||||
if (e.isPopupTrigger())
|
||||
{
|
||||
popup.show(component, e.getX() + 3, e.getY() + 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
showMenuIfPopupTrigger(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
showMenuIfPopupTrigger(e);
|
||||
}
|
||||
}
|
||||
}
|
24
L2ClientDat/java/com/l2jmobius/listeners/FormatListener.java
Normal file
24
L2ClientDat/java/com/l2jmobius/listeners/FormatListener.java
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.listeners;
|
||||
|
||||
public interface FormatListener
|
||||
{
|
||||
public String decode(String var1);
|
||||
|
||||
public String encode(String var1);
|
||||
}
|
188
L2ClientDat/java/com/l2jmobius/util/ByteReader.java
Normal file
188
L2ClientDat/java/com/l2jmobius/util/ByteReader.java
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.util;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class ByteReader
|
||||
{
|
||||
private static Charset defaultCharset = Charset.forName("cp1252");
|
||||
private static Charset utf16leCharset = Charset.forName("utf-16le");
|
||||
|
||||
public static char readChar(ByteBuffer buffer)
|
||||
{
|
||||
return (char) buffer.get();
|
||||
}
|
||||
|
||||
public static int readUByte(ByteBuffer buffer)
|
||||
{
|
||||
return buffer.get() & 255;
|
||||
}
|
||||
|
||||
public static int readInt(ByteBuffer buffer)
|
||||
{
|
||||
return Integer.reverseBytes(buffer.getInt());
|
||||
}
|
||||
|
||||
public static int readUInt(ByteBuffer buffer)
|
||||
{
|
||||
return ByteReader.readInt(buffer);
|
||||
}
|
||||
|
||||
public static short readShort(ByteBuffer buffer)
|
||||
{
|
||||
return Short.reverseBytes(buffer.getShort());
|
||||
}
|
||||
|
||||
public static double readDouble(ByteBuffer buffer)
|
||||
{
|
||||
return Double.longBitsToDouble(Long.reverseBytes(buffer.getLong()));
|
||||
}
|
||||
|
||||
public static long readLong(ByteBuffer buffer)
|
||||
{
|
||||
return Long.reverseBytes(buffer.getLong());
|
||||
}
|
||||
|
||||
public static float readFloat(ByteBuffer buffer)
|
||||
{
|
||||
return Float.intBitsToFloat(Integer.reverseBytes(buffer.getInt()));
|
||||
}
|
||||
|
||||
public static int readCompactInt(ByteBuffer input) throws IOException
|
||||
{
|
||||
int output = 0;
|
||||
boolean signed = false;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
int x = input.get() & 255;
|
||||
if (x < 0)
|
||||
{
|
||||
throw new EOFException();
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
if ((x & 128) > 0)
|
||||
{
|
||||
signed = true;
|
||||
}
|
||||
output |= x & 63;
|
||||
if ((x & 64) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i == 4)
|
||||
{
|
||||
output |= (x & 31) << 27;
|
||||
continue;
|
||||
}
|
||||
output |= (x & 127) << (6 + ((i - 1) * 7));
|
||||
if ((x & 128) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (signed)
|
||||
{
|
||||
output *= -1;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static String readRGB(ByteBuffer buffer)
|
||||
{
|
||||
String g;
|
||||
String b;
|
||||
String r = Integer.toHexString(buffer.get() & 255).toUpperCase();
|
||||
if (r.length() < 2)
|
||||
{
|
||||
r = "0" + r;
|
||||
}
|
||||
if ((g = Integer.toHexString(buffer.get() & 255).toUpperCase()).length() < 2)
|
||||
{
|
||||
g = "0" + g;
|
||||
}
|
||||
if ((b = Integer.toHexString(buffer.get() & 255).toUpperCase()).length() < 2)
|
||||
{
|
||||
b = "0" + b;
|
||||
}
|
||||
return r + g + b;
|
||||
}
|
||||
|
||||
public static String readRGBA(ByteBuffer buffer)
|
||||
{
|
||||
String a = Integer.toHexString(buffer.get() & 255).toUpperCase();
|
||||
if (a.length() < 2)
|
||||
{
|
||||
a = "0" + a;
|
||||
}
|
||||
return a + ByteReader.readRGB(buffer);
|
||||
}
|
||||
|
||||
public static String readUtfString(ByteBuffer buffer, boolean isRaw) throws Exception
|
||||
{
|
||||
int size = ByteReader.readInt(buffer);
|
||||
if (size <= 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (size > 1000000)
|
||||
{
|
||||
throw new Exception("To much data.");
|
||||
}
|
||||
byte[] bytes = new byte[size];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < size; i += 2)
|
||||
{
|
||||
bytes[i + 1] = buffer.get();
|
||||
bytes[i] = buffer.get();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ByteReader.checkAndReplaceNewLine(isRaw, new String(new String(bytes, "Unicode").getBytes("UTF-8"), "UTF-8"));
|
||||
}
|
||||
|
||||
public static String readString(ByteBuffer input, boolean isRaw) throws IOException
|
||||
{
|
||||
int len = ByteReader.readCompactInt(input);
|
||||
if (len == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
byte[] bytes = new byte[len > 0 ? len : -2 * len];
|
||||
input.get(bytes);
|
||||
return ByteReader.checkAndReplaceNewLine(isRaw, new String(bytes, 0, bytes.length - (len > 0 ? 1 : 2), len > 0 ? defaultCharset : utf16leCharset).intern());
|
||||
}
|
||||
|
||||
private static String checkAndReplaceNewLine(boolean isRaw, String str)
|
||||
{
|
||||
if (!isRaw && str.contains("\r\n"))
|
||||
{
|
||||
str = str.replace("\r\n", "\\r\\n");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
211
L2ClientDat/java/com/l2jmobius/util/ByteWriter.java
Normal file
211
L2ClientDat/java/com/l2jmobius/util/ByteWriter.java
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.util;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class ByteWriter
|
||||
{
|
||||
private static final ByteOrder BYTE_ORDER = ByteOrder.LITTLE_ENDIAN;
|
||||
private static Charset defaultCharset = Charset.forName("ascii");
|
||||
private static Charset utf16leCharset = Charset.forName("utf-16le");
|
||||
|
||||
public static Buffer writeChar(byte value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1).order(BYTE_ORDER);
|
||||
buffer.put(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeCompactInt(int count)
|
||||
{
|
||||
byte[] b = ByteWriter.compactIntToByteArray(count);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(b.length).order(BYTE_ORDER);
|
||||
buffer.put(b);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeByte(byte value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1).order(BYTE_ORDER);
|
||||
buffer.put(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeUByte(short value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1).order(BYTE_ORDER);
|
||||
buffer.put((byte) value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeInt(int value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4).order(BYTE_ORDER);
|
||||
buffer.putInt(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeUInt(int value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4).order(BYTE_ORDER);
|
||||
buffer.putInt(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeShort(short value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(2).order(BYTE_ORDER);
|
||||
buffer.putShort(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeUShort(int value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(2).order(BYTE_ORDER);
|
||||
buffer.put((byte) (value & 255));
|
||||
buffer.put((byte) ((value & 65280) >> 8));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeRGB(String rgb)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(3).order(BYTE_ORDER);
|
||||
buffer.put((byte) Integer.parseInt(rgb.substring(0, 2), 16));
|
||||
buffer.put((byte) Integer.parseInt(rgb.substring(2, 4), 16));
|
||||
buffer.put((byte) Integer.parseInt(rgb.substring(4, 6), 16));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeRGBA(String rgba)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4).order(BYTE_ORDER);
|
||||
buffer.put((byte[]) ByteWriter.writeRGB(rgba.substring(0, 6)).array());
|
||||
buffer.put((byte) Integer.parseInt(rgba.substring(6, 8), 16));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeUtfString(String str, boolean isRaw)
|
||||
{
|
||||
int size = str.length();
|
||||
if (size <= 0)
|
||||
{
|
||||
return ByteBuffer.allocate(4).order(BYTE_ORDER).putInt(0);
|
||||
}
|
||||
if (!isRaw)
|
||||
{
|
||||
str = ByteWriter.checkAndReplaceNewLine(str);
|
||||
size = str.length();
|
||||
}
|
||||
ByteBuffer buffer = ByteBuffer.allocate((size * 2) + 4).order(BYTE_ORDER);
|
||||
buffer.putInt(size * 2);
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
buffer.putChar(str.charAt(i));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeString(String s, boolean isRaw)
|
||||
{
|
||||
if ((s == null) || s.isEmpty())
|
||||
{
|
||||
return ByteWriter.writeCompactInt(0);
|
||||
}
|
||||
if (!isRaw)
|
||||
{
|
||||
s = ByteWriter.checkAndReplaceNewLine(s);
|
||||
}
|
||||
s = s + '\u0000';
|
||||
boolean def = defaultCharset.newEncoder().canEncode(s);
|
||||
byte[] bytes = s.getBytes(def ? defaultCharset : utf16leCharset);
|
||||
byte[] bSize = ByteWriter.compactIntToByteArray(def ? bytes.length : (-bytes.length) / 2);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(bytes.length + bSize.length).order(BYTE_ORDER);
|
||||
buffer.put(bSize);
|
||||
buffer.put(bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeDouble(double value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(8).order(BYTE_ORDER);
|
||||
buffer.putDouble(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeFloat(float value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4).order(BYTE_ORDER);
|
||||
buffer.putFloat(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Buffer writeLong(long value)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(8).order(BYTE_ORDER);
|
||||
buffer.putLong(value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] compactIntToByteArray(int v)
|
||||
{
|
||||
boolean negative = v < 0;
|
||||
v = Math.abs(v);
|
||||
int[] bytes = new int[]
|
||||
{
|
||||
v & 63,
|
||||
(v >> 6) & 127,
|
||||
(v >> 13) & 127,
|
||||
(v >> 20) & 127,
|
||||
(v >> 27) & 127
|
||||
};
|
||||
if (negative)
|
||||
{
|
||||
int[] arrn = bytes;
|
||||
arrn[0] = arrn[0] | 128;
|
||||
}
|
||||
int size = 5;
|
||||
for (int i = 4; (i > 0) && (bytes[i] == 0); --i)
|
||||
{
|
||||
--size;
|
||||
}
|
||||
byte[] res = new byte[size];
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
if (i != (size - 1))
|
||||
{
|
||||
int[] arrn = bytes;
|
||||
int n = i;
|
||||
arrn[n] = arrn[n] | (i == 0 ? 64 : 128);
|
||||
}
|
||||
res[i] = (byte) bytes[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static String checkAndReplaceNewLine(String str)
|
||||
{
|
||||
if (str.contains("\\r\\n"))
|
||||
{
|
||||
str = str.replace("\\r\\n", "\r\n");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
85
L2ClientDat/java/com/l2jmobius/util/DebugUtil.java
Normal file
85
L2ClientDat/java/com/l2jmobius/util/DebugUtil.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.xml.DOMConfigurator;
|
||||
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.xml.Variant;
|
||||
|
||||
public class DebugUtil
|
||||
{
|
||||
private static Logger _log = LogManager.getLogger(DebugUtil.class);
|
||||
|
||||
public static void debug(String message)
|
||||
{
|
||||
if (ConfigDebug.DAT_DEBUG_MSG)
|
||||
{
|
||||
_log.info(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void debugPos(int pos, String name, Variant val)
|
||||
{
|
||||
if (ConfigDebug.DAT_DEBUG_POS)
|
||||
{
|
||||
_log.info("pos: " + pos + " " + name + ": " + val);
|
||||
if ((ConfigDebug.DAT_DEBUG_POS_LIMIT != 0) && (pos > ConfigDebug.DAT_DEBUG_POS_LIMIT))
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void save(ByteBuffer buffer, File path)
|
||||
{
|
||||
if (ConfigDebug.SAVE_DECODE)
|
||||
{
|
||||
try
|
||||
{
|
||||
String unpackDirPath = path.getParent() + "/" + "!decrypted";
|
||||
File decryptedDir = new File(unpackDirPath);
|
||||
decryptedDir.mkdir();
|
||||
File file = new File(decryptedDir + "/" + path.getName());
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(buffer.array());
|
||||
fos.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Logger getLogger()
|
||||
{
|
||||
return _log;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
DOMConfigurator.configure("./config/log4j.xml");
|
||||
}
|
||||
}
|
338
L2ClientDat/java/com/l2jmobius/util/Util.java
Normal file
338
L2ClientDat/java/com/l2jmobius/util/Util.java
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
public class Util
|
||||
{
|
||||
public static void printBytes(String name, byte[] buffer)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(buffer.length);
|
||||
builder.append(name).append(": [");
|
||||
for (byte b : buffer)
|
||||
{
|
||||
builder.append(b).append(" ");
|
||||
}
|
||||
builder.append("]");
|
||||
DebugUtil.getLogger().info(builder.toString());
|
||||
}
|
||||
|
||||
public static boolean compareBuffers(byte[] b1, byte[] b2)
|
||||
{
|
||||
if ((b1 == null) || (b2 == null) || (b1.length != b2.length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < b1.length; ++i)
|
||||
{
|
||||
if (b1[i] == b2[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String printData(byte[] data, int len)
|
||||
{
|
||||
int a;
|
||||
int charpoint;
|
||||
byte t1;
|
||||
StringBuilder result = new StringBuilder();
|
||||
int counter = 0;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if ((counter % 16) == 0)
|
||||
{
|
||||
result.append(Util.fillHex(i, 4) + ": ");
|
||||
}
|
||||
result.append(Util.fillHex(data[i] & 255, 2) + " ");
|
||||
if (++counter != 16)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result.append(" ");
|
||||
charpoint = i - 15;
|
||||
for (a = 0; a < 16; ++a)
|
||||
{
|
||||
if (((t1 = data[charpoint++]) > 31) && (t1 < 128))
|
||||
{
|
||||
result.append((char) t1);
|
||||
continue;
|
||||
}
|
||||
result.append('.');
|
||||
}
|
||||
result.append("\n");
|
||||
counter = 0;
|
||||
}
|
||||
int rest = data.length % 16;
|
||||
if (rest > 0)
|
||||
{
|
||||
for (int i = 0; i < (17 - rest); ++i)
|
||||
{
|
||||
result.append(" ");
|
||||
}
|
||||
charpoint = data.length - rest;
|
||||
for (a = 0; a < rest; ++a)
|
||||
{
|
||||
if (((t1 = data[charpoint++]) > 31) && (t1 < 128))
|
||||
{
|
||||
result.append((char) t1);
|
||||
continue;
|
||||
}
|
||||
result.append('.');
|
||||
}
|
||||
result.append("\n");
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static String fillHex(int data, int digits)
|
||||
{
|
||||
String number = Integer.toHexString(data);
|
||||
for (int i = number.length(); i < digits; ++i)
|
||||
{
|
||||
number = "0" + number;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
public static String printData(byte[] blop)
|
||||
{
|
||||
return Util.printData(blop, blop.length);
|
||||
}
|
||||
|
||||
public static List<File> loadFiles(String dir, String prefix)
|
||||
{
|
||||
ArrayList<File> list = new ArrayList<>();
|
||||
File folder = new File(dir);
|
||||
for (File listOfFile : folder.listFiles())
|
||||
{
|
||||
if (listOfFile.isFile())
|
||||
{
|
||||
if (!listOfFile.getName().endsWith(prefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(listOfFile);
|
||||
continue;
|
||||
}
|
||||
if (!listOfFile.isDirectory())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
File folder2 = new File(dir + listOfFile.getName() + "/");
|
||||
for (File aListOfFiles2 : folder2.listFiles())
|
||||
{
|
||||
if (!aListOfFiles2.getName().endsWith(prefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(aListOfFiles2);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static String[] getDirsNames(String dir, String prefix)
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
File folder = new File(dir);
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
if (listOfFiles == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (File listOfFile : listOfFiles)
|
||||
{
|
||||
if (!listOfFile.isDirectory() || !listOfFile.getName().endsWith(prefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(listOfFile.getName());
|
||||
}
|
||||
String[] text = new String[list.size()];
|
||||
int i = 0;
|
||||
Iterator<String> iterator = list.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
text[i] = iterator.next();
|
||||
++i;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String[] getFilesNames(String dir, String prefix)
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
File folder = new File(dir);
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
if (listOfFiles == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (File listOfFile : listOfFiles)
|
||||
{
|
||||
if (!listOfFile.isFile() || !listOfFile.getName().endsWith(prefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(listOfFile.getName().replace(prefix, ""));
|
||||
}
|
||||
String[] text = new String[list.size()];
|
||||
int i = 0;
|
||||
Iterator<String> iterator = list.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
text[i] = iterator.next();
|
||||
++i;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String printData(ByteBuffer buf)
|
||||
{
|
||||
byte[] data = new byte[buf.remaining()];
|
||||
buf.get(data);
|
||||
String hex = Util.printData(data, data.length);
|
||||
buf.position(buf.position() - data.length);
|
||||
return hex;
|
||||
}
|
||||
|
||||
public static List<String> splitList(String s)
|
||||
{
|
||||
if (s.startsWith("{"))
|
||||
{
|
||||
s = s.substring(1, s.length() - 1);
|
||||
}
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
StringBuffer buff = new StringBuffer();
|
||||
int level = 0;
|
||||
for (char part : s.toCharArray())
|
||||
{
|
||||
if ((part == '{') || (part == '['))
|
||||
{
|
||||
++level;
|
||||
}
|
||||
else if ((part == '}') || (part == ']'))
|
||||
{
|
||||
--level;
|
||||
}
|
||||
else if ((part == ';') && (level == 0))
|
||||
{
|
||||
res.add(buff.toString());
|
||||
buff = new StringBuffer();
|
||||
continue;
|
||||
}
|
||||
buff.append(part);
|
||||
}
|
||||
res.add(buff.toString());
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Map<String, String> stringToMap(String id)
|
||||
{
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
for (String str : id.split("\t"))
|
||||
{
|
||||
if (!str.contains("="))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int index = str.indexOf("=");
|
||||
String key = str.substring(0, index);
|
||||
String val = str.substring(index + 1, str.length());
|
||||
map.put(key, val);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static String mapToString(Map<String, String> map)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String key : map.keySet())
|
||||
{
|
||||
builder.append(key).append("=").append(map.get(key)).append("\t");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings(
|
||||
{
|
||||
"rawtypes",
|
||||
"unchecked"
|
||||
})
|
||||
public static void compileJavaClass(String sourceFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
DiagnosticCollector diagnostics = new DiagnosticCollector();
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
|
||||
Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjectsFromFiles(Util.loadFiles(sourceFile, ".java"));
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnit);
|
||||
if (!task.call().booleanValue())
|
||||
{
|
||||
for (Object diagnostic : diagnostics.getDiagnostics())
|
||||
{
|
||||
final Diagnostic d = (Diagnostic) diagnostic;
|
||||
System.out.format("Error on line %d in %s%n", d.getLineNumber(), ((JavaFileObject) d.getSource()).toUri());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object loadJavaClass(String className, String path)
|
||||
{
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("resource")
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[]
|
||||
{
|
||||
new File(path).toURI().toURL()
|
||||
});
|
||||
Class<?> loadedClass = classLoader.loadClass(className);
|
||||
return loadedClass.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
148
L2ClientDat/java/com/l2jmobius/xml/CryptVersionParser.java
Normal file
148
L2ClientDat/java/com/l2jmobius/xml/CryptVersionParser.java
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.clientcryptor.crypt.BlowFishDatCrypter;
|
||||
import com.l2jmobius.clientcryptor.crypt.DESDatCrypter;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.clientcryptor.crypt.RSADatCrypter;
|
||||
import com.l2jmobius.clientcryptor.crypt.XorDatCrypter;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
|
||||
public class CryptVersionParser
|
||||
{
|
||||
private static Map<String, DatCrypter> encryptKeys = new LinkedHashMap<>();
|
||||
private static Map<String, DatCrypter> decryptKeys = new LinkedHashMap<>();
|
||||
private static CryptVersionParser _parser = new CryptVersionParser();
|
||||
|
||||
public static CryptVersionParser getInstance()
|
||||
{
|
||||
return _parser;
|
||||
}
|
||||
|
||||
private CryptVersionParser()
|
||||
{
|
||||
CryptVersionParser.parseCryptVersion();
|
||||
}
|
||||
|
||||
private static void parseCryptVersion()
|
||||
{
|
||||
File def = new File("./config/cryptVersion.xml");
|
||||
if (def.exists())
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
factory.setIgnoringComments(true);
|
||||
try
|
||||
{
|
||||
Document doc = factory.newDocumentBuilder().parse(def);
|
||||
Node defsNode = doc.getFirstChild();
|
||||
while (defsNode != null)
|
||||
{
|
||||
if (defsNode.getNodeName().equals("keys"))
|
||||
{
|
||||
for (Node defNode = defsNode.getFirstChild(); defNode != null; defNode = defNode.getNextSibling())
|
||||
{
|
||||
if (!defNode.getNodeName().equals("key"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String name = defNode.getAttributes().getNamedItem("name").getNodeValue();
|
||||
String type = defNode.getAttributes().getNamedItem("type").getNodeValue().toLowerCase();
|
||||
int code = Integer.parseInt(defNode.getAttributes().getNamedItem("code").getNodeValue().toLowerCase());
|
||||
boolean isDecrypt = Boolean.parseBoolean(defNode.getAttributes().getNamedItem("decrypt").getNodeValue());
|
||||
boolean useStructure = Boolean.parseBoolean(defNode.getAttributes().getNamedItem("useStructure").getNodeValue());
|
||||
String extension = defNode.getAttributes().getNamedItem("extension").getNodeValue();
|
||||
DatCrypter dat = null;
|
||||
switch (type)
|
||||
{
|
||||
case "rsa":
|
||||
{
|
||||
String modulus = defNode.getAttributes().getNamedItem("modulus").getNodeValue();
|
||||
String exp = defNode.getAttributes().getNamedItem("exp").getNodeValue();
|
||||
dat = new RSADatCrypter(code, modulus, exp, isDecrypt);
|
||||
break;
|
||||
}
|
||||
case "xor":
|
||||
{
|
||||
dat = new XorDatCrypter(code, Integer.parseInt(defNode.getAttributes().getNamedItem("key").getNodeValue()), isDecrypt);
|
||||
break;
|
||||
}
|
||||
case "blowfish":
|
||||
{
|
||||
dat = new BlowFishDatCrypter(code, defNode.getAttributes().getNamedItem("key").getNodeValue(), isDecrypt);
|
||||
break;
|
||||
}
|
||||
case "des":
|
||||
{
|
||||
dat = new DESDatCrypter(code, defNode.getAttributes().getNamedItem("key").getNodeValue(), isDecrypt);
|
||||
}
|
||||
}
|
||||
if (dat == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dat.addFileExtension(extension);
|
||||
dat.setUseStructure(useStructure);
|
||||
if (isDecrypt)
|
||||
{
|
||||
decryptKeys.put(name, dat);
|
||||
continue;
|
||||
}
|
||||
encryptKeys.put(name, dat);
|
||||
}
|
||||
}
|
||||
defsNode = doc.getNextSibling();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, DatCrypter> getEncryptKey()
|
||||
{
|
||||
return encryptKeys;
|
||||
}
|
||||
|
||||
public Map<String, DatCrypter> getDecryptKeys()
|
||||
{
|
||||
return decryptKeys;
|
||||
}
|
||||
|
||||
public DatCrypter getEncryptKey(String s)
|
||||
{
|
||||
return encryptKeys.get(s);
|
||||
}
|
||||
|
||||
public DatCrypter getDecryptKey(String s)
|
||||
{
|
||||
return decryptKeys.get(s);
|
||||
}
|
||||
}
|
84
L2ClientDat/java/com/l2jmobius/xml/Descriptor.java
Normal file
84
L2ClientDat/java/com/l2jmobius/xml/Descriptor.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.listeners.FormatListener;
|
||||
|
||||
public class Descriptor
|
||||
{
|
||||
private final String _alias;
|
||||
private final String _filePattern;
|
||||
private final List<ParamNode> _nodes;
|
||||
private boolean _isRawData;
|
||||
private boolean _isSafePackage;
|
||||
private FormatListener _format;
|
||||
|
||||
Descriptor(String alias, String filePattern, List<ParamNode> nodes)
|
||||
{
|
||||
_alias = alias;
|
||||
_filePattern = filePattern;
|
||||
_nodes = nodes;
|
||||
_isRawData = false;
|
||||
}
|
||||
|
||||
void setIsRawData(boolean value)
|
||||
{
|
||||
_isRawData = value;
|
||||
}
|
||||
|
||||
public void setIsSafePackage(boolean value)
|
||||
{
|
||||
_isSafePackage = value;
|
||||
}
|
||||
|
||||
boolean isRawData()
|
||||
{
|
||||
return _isRawData;
|
||||
}
|
||||
|
||||
public boolean isSafePackage()
|
||||
{
|
||||
return _isSafePackage;
|
||||
}
|
||||
|
||||
public String getAlias()
|
||||
{
|
||||
return _alias;
|
||||
}
|
||||
|
||||
public String getFilePattern()
|
||||
{
|
||||
return _filePattern;
|
||||
}
|
||||
|
||||
List<ParamNode> getNodes()
|
||||
{
|
||||
return _nodes;
|
||||
}
|
||||
|
||||
public void setFormat(FormatListener format)
|
||||
{
|
||||
_format = format;
|
||||
}
|
||||
|
||||
public FormatListener getFormat()
|
||||
{
|
||||
return _format;
|
||||
}
|
||||
}
|
53
L2ClientDat/java/com/l2jmobius/xml/DescriptorLink.java
Normal file
53
L2ClientDat/java/com/l2jmobius/xml/DescriptorLink.java
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
public class DescriptorLink
|
||||
{
|
||||
private final String dir;
|
||||
private final String namePattern;
|
||||
private final String linkFile;
|
||||
private final String linkVersion;
|
||||
|
||||
public DescriptorLink(String dir, String namePattern, String linkFile, String linkVersion)
|
||||
{
|
||||
this.dir = dir;
|
||||
this.namePattern = namePattern;
|
||||
this.linkFile = linkFile;
|
||||
this.linkVersion = linkVersion;
|
||||
}
|
||||
|
||||
public String getFilePattern()
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
|
||||
public String getNamePattern()
|
||||
{
|
||||
return namePattern;
|
||||
}
|
||||
|
||||
public String getLinkFile()
|
||||
{
|
||||
return linkFile;
|
||||
}
|
||||
|
||||
public String getLinkVersion()
|
||||
{
|
||||
return linkVersion;
|
||||
}
|
||||
}
|
368
L2ClientDat/java/com/l2jmobius/xml/DescriptorParser.java
Normal file
368
L2ClientDat/java/com/l2jmobius/xml/DescriptorParser.java
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.listeners.FormatListener;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.util.Util;
|
||||
import com.l2jmobius.xml.exceptions.CycleArgumentException;
|
||||
|
||||
public class DescriptorParser
|
||||
{
|
||||
private static DescriptorParser _parser = new DescriptorParser();
|
||||
private final Map<String, Map<String, Descriptor>> _descriptors = new HashMap<>();
|
||||
private final Map<String, List<ParamNode>> _definitions = new HashMap<>();
|
||||
private final Map<String, List<DescriptorLink>> _links = new HashMap<>();
|
||||
|
||||
private DescriptorParser()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
public static DescriptorParser getInstance()
|
||||
{
|
||||
return _parser;
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
parseDefinitions();
|
||||
Util.loadFiles("./structure/", ".xml").forEach(this::parseDescriptor);
|
||||
}
|
||||
|
||||
private void parseDefinitions()
|
||||
{
|
||||
File def = new File("./!definitions.xml");
|
||||
if (def.exists())
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
factory.setIgnoringComments(true);
|
||||
try
|
||||
{
|
||||
Document doc = factory.newDocumentBuilder().parse(def);
|
||||
Node defsNode = doc.getFirstChild();
|
||||
while (defsNode != null)
|
||||
{
|
||||
if (defsNode.getNodeName().equals("definitions"))
|
||||
{
|
||||
for (Node defNode = defsNode.getFirstChild(); defNode != null; defNode = defNode.getNextSibling())
|
||||
{
|
||||
if (!defNode.getNodeName().equals("definition"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String defName = defNode.getAttributes().getNamedItem("name").getNodeValue();
|
||||
List<ParamNode> nodes = parseNodes(defNode, true, new HashSet<String>(), "definitions->" + defName);
|
||||
_definitions.put(defName, nodes);
|
||||
}
|
||||
}
|
||||
defsNode = doc.getNextSibling();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDescriptor(File file)
|
||||
{
|
||||
if (!file.exists())
|
||||
{
|
||||
DebugUtil.debug("File " + file.getName() + " not found.");
|
||||
}
|
||||
try
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
factory.setIgnoringComments(true);
|
||||
Document doc = factory.newDocumentBuilder().parse(file);
|
||||
Node fileNode0 = doc.getFirstChild();
|
||||
while (fileNode0 != null)
|
||||
{
|
||||
if (fileNode0.getNodeName().equalsIgnoreCase("list"))
|
||||
{
|
||||
for (Node fileNode = fileNode0.getFirstChild(); fileNode != null; fileNode = fileNode.getNextSibling())
|
||||
{
|
||||
String dir;
|
||||
Object obj;
|
||||
String namePattern;
|
||||
Map<String, Descriptor> versions;
|
||||
if (fileNode.getNodeName().equalsIgnoreCase("link"))
|
||||
{
|
||||
dir = file.getName().substring(0, file.getName().length() - 4);
|
||||
namePattern = fileNode.getAttributes().getNamedItem("pattern").getNodeValue();
|
||||
String linkFile = fileNode.getAttributes().getNamedItem("file").getNodeValue();
|
||||
String linkVersion = fileNode.getAttributes().getNamedItem("version").getNodeValue();
|
||||
List<DescriptorLink> list = _links.get(dir);
|
||||
if (list == null)
|
||||
{
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
list.add(new DescriptorLink(dir, namePattern, linkFile, linkVersion));
|
||||
_links.put(dir, list);
|
||||
continue;
|
||||
}
|
||||
if (!fileNode.getNodeName().equalsIgnoreCase("file"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dir = file.getName().substring(0, file.getName().length() - 4);
|
||||
namePattern = fileNode.getAttributes().getNamedItem("pattern").getNodeValue();
|
||||
boolean isRawData = parseBoolNode(fileNode, "isRaw", false);
|
||||
boolean isSafePackage = parseBoolNode(fileNode, "isSafePackage", false);
|
||||
String formatName = parseStringNode(fileNode, "format", null);
|
||||
DebugUtil.debug("Boot of parsing file: " + namePattern);
|
||||
List<ParamNode> nodes = parseNodes(fileNode, false, new HashSet<String>(), dir + "->" + namePattern);
|
||||
Descriptor desc = new Descriptor(file.getName(), namePattern, nodes);
|
||||
desc.setIsRawData(isRawData);
|
||||
desc.setIsSafePackage(isSafePackage);
|
||||
if ((formatName != null) && ((obj = Util.loadJavaClass(formatName, "./structure/format/")) instanceof FormatListener))
|
||||
{
|
||||
desc.setFormat((FormatListener) obj);
|
||||
}
|
||||
if ((versions = _descriptors.get(dir)) == null)
|
||||
{
|
||||
versions = new HashMap<>();
|
||||
}
|
||||
versions.put(namePattern, desc);
|
||||
_descriptors.put(dir, versions);
|
||||
DebugUtil.debug("End of parsing file: " + namePattern);
|
||||
}
|
||||
}
|
||||
fileNode0 = doc.getNextSibling();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ParamNode> parseNodes(Node fileNode, boolean isHideName, Set<String> names, String fileName) throws Exception
|
||||
{
|
||||
HashMap<String, Integer> defsCounter = new HashMap<>();
|
||||
LinkedList<ParamNode> nodes = new LinkedList<>();
|
||||
for (Node node = fileNode.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
ParamNode beginNode;
|
||||
String nodeName = node.getNodeName();
|
||||
if (nodeName.equals("#text"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
boolean isHide = isHideName || parseBoolNode(node, "hidden", true);
|
||||
if (node.getAttributes().getNamedItem("name") == null)
|
||||
{
|
||||
DebugUtil.getLogger().warn("Node name == null, fileName: " + fileName);
|
||||
continue;
|
||||
}
|
||||
String entityName = node.getAttributes().getNamedItem("name").getNodeValue();
|
||||
if (nodeName.equalsIgnoreCase("node"))
|
||||
{
|
||||
String type = node.getAttributes().getNamedItem("reader").getNodeValue();
|
||||
if (_definitions.containsKey(type))
|
||||
{
|
||||
if (!defsCounter.containsKey(type))
|
||||
{
|
||||
defsCounter.put(type, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
defsCounter.put(type, defsCounter.get(type) + 1);
|
||||
}
|
||||
List<ParamNode> defNodes = _definitions.get(type);
|
||||
for (ParamNode defNode : defNodes)
|
||||
{
|
||||
ParamNode copied = defNode.copy();
|
||||
copied.setName(entityName);
|
||||
if (isHide)
|
||||
{
|
||||
copied.setHidden();
|
||||
}
|
||||
nodes.add(copied);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParamNode dataNode = new ParamNode(entityName, ParamNodeType.VARIABLE, ParamType.valueOf(type));
|
||||
if (isHide)
|
||||
{
|
||||
dataNode.setHidden();
|
||||
}
|
||||
nodes.add(dataNode);
|
||||
DebugUtil.debug("Found node: " + dataNode.getName());
|
||||
}
|
||||
if (names.contains(entityName))
|
||||
{
|
||||
DebugUtil.getLogger().warn("Node name duplicated [" + entityName + "] fileName: " + fileName);
|
||||
}
|
||||
names.add(entityName);
|
||||
continue;
|
||||
}
|
||||
if (nodeName.equalsIgnoreCase("for"))
|
||||
{
|
||||
String iteratorName = entityName;
|
||||
boolean skipWriteSize = parseBoolNode(node, "skipWriteSize", false);
|
||||
int size = -1;
|
||||
if (node.getAttributes().getNamedItem("size") != null)
|
||||
{
|
||||
String sizeStr = node.getAttributes().getNamedItem("size").getNodeValue();
|
||||
if (sizeStr.startsWith("#"))
|
||||
{
|
||||
iteratorName = sizeStr.substring(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = Integer.parseInt(sizeStr);
|
||||
}
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
DebugUtil.getLogger().warn("Size of cycle [" + iteratorName + "] was set to zero. Deprecated cycle?");
|
||||
}
|
||||
DebugUtil.debug("Found cycle for variable: " + entityName);
|
||||
ParamNode beginNode2 = new ParamNode(entityName, ParamNodeType.FOR, null);
|
||||
if (size >= 0)
|
||||
{
|
||||
beginNode2.setSize(size);
|
||||
}
|
||||
if (isHide)
|
||||
{
|
||||
beginNode2.setHidden();
|
||||
}
|
||||
beginNode2.setSkipWriteSize(skipWriteSize);
|
||||
beginNode2.addSubNodes(parseNodes(node, false, names, fileName));
|
||||
beginNode2.setCycleName(iteratorName);
|
||||
nodes.add(beginNode2);
|
||||
boolean iteratorFound = false;
|
||||
for (ParamNode n : nodes)
|
||||
{
|
||||
if (!iteratorName.equals(n.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
n.setIterator();
|
||||
iteratorFound = true;
|
||||
break;
|
||||
}
|
||||
if (iteratorFound || (size >= 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
throw new CycleArgumentException("Invalid argument [" + iteratorName + "] for [cycle]");
|
||||
}
|
||||
if (nodeName.equalsIgnoreCase("wrapper"))
|
||||
{
|
||||
beginNode = new ParamNode(entityName, ParamNodeType.WRAPPER, null);
|
||||
beginNode.addSubNodes(parseNodes(node, true, names, fileName));
|
||||
nodes.add(beginNode);
|
||||
DebugUtil.debug("Found [wrapper] data " + entityName);
|
||||
continue;
|
||||
}
|
||||
if (nodeName.equalsIgnoreCase("write"))
|
||||
{
|
||||
beginNode = new ParamNode(entityName, ParamNodeType.CONSTANT, ParamType.STRING);
|
||||
beginNode.setHidden();
|
||||
nodes.add(beginNode);
|
||||
DebugUtil.debug("Found [constant] data: " + entityName);
|
||||
continue;
|
||||
}
|
||||
if (!nodeName.equalsIgnoreCase("if"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String paramName = node.getAttributes().getNamedItem("param").getNodeValue();
|
||||
String vsl = node.getAttributes().getNamedItem("val").getNodeValue();
|
||||
if (!paramName.startsWith("#"))
|
||||
{
|
||||
throw new Exception("Invalid argument [" + entityName + "] for [if]");
|
||||
}
|
||||
paramName = paramName.substring(1);
|
||||
ParamNode beginNode3 = new ParamNode(entityName, ParamNodeType.IF, null);
|
||||
beginNode3.setParamIf(paramName);
|
||||
beginNode3.setValIf(vsl);
|
||||
beginNode3.addSubNodes(parseNodes(node, false, names, fileName));
|
||||
nodes.add(beginNode3);
|
||||
DebugUtil.debug("Found [if] data: " + entityName);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public Descriptor findDescriptorForFile(String dir, String fileName)
|
||||
{
|
||||
List<DescriptorLink> listDes = _links.get(dir);
|
||||
if (listDes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (DescriptorLink desc : listDes)
|
||||
{
|
||||
Map<String, Descriptor> versions;
|
||||
if (!fileName.toLowerCase().matches(desc.getNamePattern().toLowerCase()) || !_descriptors.containsKey(desc.getLinkFile()) || !(versions = _descriptors.get(desc.getLinkFile())).containsKey(desc.getLinkVersion()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return versions.get(desc.getLinkVersion());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean parseBoolNode(Node node, String name, boolean def)
|
||||
{
|
||||
if (node.getAttributes() == null)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if (node.getAttributes().getNamedItem(name) == null)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return node.getAttributes().getNamedItem(name).getNodeValue().equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
private String parseStringNode(Node node, String name, String def)
|
||||
{
|
||||
if (node.getAttributes() == null)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if (node.getAttributes().getNamedItem(name) == null)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return node.getAttributes().getNamedItem(name).getNodeValue();
|
||||
}
|
||||
}
|
395
L2ClientDat/java/com/l2jmobius/xml/DescriptorReader.java
Normal file
395
L2ClientDat/java/com/l2jmobius/xml/DescriptorReader.java
Normal file
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.L2ClientDat;
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.util.ByteReader;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
|
||||
public class DescriptorReader
|
||||
{
|
||||
private static DescriptorReader _instance = new DescriptorReader();
|
||||
final String eq = "=";
|
||||
final String tab = "\t";
|
||||
final String nl = System.getProperty("line.separator");
|
||||
final String semi = ";";
|
||||
final String lb = "[";
|
||||
final String rb = "]";
|
||||
|
||||
public static DescriptorReader getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public String parseData(File currentFile, DatCrypter crypter, Descriptor desc, ByteBuffer data) throws Exception
|
||||
{
|
||||
String stringData;
|
||||
if (desc.isRawData())
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
readVariables(currentFile, crypter, desc.getNodes().get(0), new HashMap<String, Variant>(), data, builder, true);
|
||||
stringData = builder.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
stringData = this.parseData(currentFile, crypter, data, null, desc.getNodes(), 1, new HashMap<String, Variant>(), false, 0).trim();
|
||||
}
|
||||
if (desc.getFormat() != null)
|
||||
{
|
||||
stringData = desc.getFormat().decode(stringData);
|
||||
}
|
||||
int pos = desc.isSafePackage() ? data.position() + 13 : data.position();
|
||||
if (data.limit() > pos)
|
||||
{
|
||||
L2ClientDat.addLogConsole("Unpacked not full " + data.position() + "/" + data.limit() + " diff: " + (data.limit() - pos), true);
|
||||
}
|
||||
return stringData;
|
||||
}
|
||||
|
||||
private String parseData(File currentFile, DatCrypter crypter, ByteBuffer data, ParamNode lastNode, List<ParamNode> nodes, int cycleSize, Map<String, Variant> vars, boolean isNameHidden, int cycleNameLevel) throws Exception
|
||||
{
|
||||
if (cycleSize > 0)
|
||||
{
|
||||
StringBuilder out = new StringBuilder();
|
||||
for (int i = 0; i < cycleSize; ++i)
|
||||
{
|
||||
boolean isAddCycleName = !isNameHidden && (lastNode != null) && lastNode.getEntityType().isCycle();
|
||||
if (isAddCycleName)
|
||||
{
|
||||
for (int k = 0; k < cycleNameLevel; ++k)
|
||||
{
|
||||
out.append("\t");
|
||||
}
|
||||
out.append(lastNode.getName().concat("_begin"));
|
||||
++cycleNameLevel;
|
||||
}
|
||||
int nodeSize = nodes.size();
|
||||
int nNode = 0;
|
||||
for (ParamNode n : nodes)
|
||||
{
|
||||
if (n.isIterator())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++nNode;
|
||||
}
|
||||
if (isNameHidden && (nNode > 1))
|
||||
{
|
||||
out.append("{");
|
||||
}
|
||||
for (int j = 0; j < nodeSize; ++j)
|
||||
{
|
||||
ParamNode node = nodes.get(j);
|
||||
if (node.getEntityType().isIf())
|
||||
{
|
||||
Variant var = vars.get(node.getParamIf());
|
||||
if ((var == null) || !var.toString().equalsIgnoreCase(node.getValIf()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
out.append(this.parseData(currentFile, crypter, data, null, node.getSubNodes(), 1, vars, isNameHidden, cycleNameLevel));
|
||||
continue;
|
||||
}
|
||||
if (!(node.isIterator() || node.getEntityType().isConstant() || isNameHidden || (!node.getEntityType().isWrapper() && !node.isNameHidden())))
|
||||
{
|
||||
out.append("\t").append(node.getName()).append("=");
|
||||
}
|
||||
if (node.getEntityType().isWrapper())
|
||||
{
|
||||
out.append(this.parseData(currentFile, crypter, data, null, node.getSubNodes(), 1, vars, true, cycleNameLevel));
|
||||
}
|
||||
else if (node.getEntityType().isCycle())
|
||||
{
|
||||
int size;
|
||||
if (node.getSize() >= 0)
|
||||
{
|
||||
size = node.getSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Variant var = vars.get(node.getCycleName());
|
||||
if (var.isInt())
|
||||
{
|
||||
size = var.getInt();
|
||||
}
|
||||
else if (var.isShort())
|
||||
{
|
||||
size = var.getShort();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Wrong cycle variable format for cycle: " + node.getName() + " iterator: " + node.getCycleName());
|
||||
}
|
||||
}
|
||||
if (node.isNameHidden())
|
||||
{
|
||||
out.append("{");
|
||||
}
|
||||
out.append(this.parseData(currentFile, crypter, data, node, node.getSubNodes(), size, vars, node.isNameHidden(), cycleNameLevel));
|
||||
if (node.isNameHidden())
|
||||
{
|
||||
out.append("}");
|
||||
}
|
||||
}
|
||||
else if (node.getEntityType().isConstant())
|
||||
{
|
||||
out.append(node.getName().replace("\\t", "\t").replace("\\r\\n", "\r\n"));
|
||||
}
|
||||
else if (node.getEntityType().isVariable())
|
||||
{
|
||||
readVariables(currentFile, crypter, node, vars, data, out, false);
|
||||
}
|
||||
if (!node.isIterator() && !node.getEntityType().isConstant() && isNameHidden && (j != (nodeSize - 1)))
|
||||
{
|
||||
out.append(";");
|
||||
}
|
||||
if (!vars.containsKey(node.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DebugUtil.debugPos(data.position(), node.getName(), vars.get(node.getName()));
|
||||
}
|
||||
if (isNameHidden)
|
||||
{
|
||||
if (nNode > 1)
|
||||
{
|
||||
out.append("}");
|
||||
}
|
||||
if (i < (cycleSize - 1))
|
||||
{
|
||||
out.append(";");
|
||||
}
|
||||
}
|
||||
if (!isAddCycleName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (out.charAt(out.length() - 1) != '\n')
|
||||
{
|
||||
out.append("\t");
|
||||
}
|
||||
out.append(lastNode.getName()).append("_end\r\n");
|
||||
--cycleNameLevel;
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void readVariables(File currentFile, DatCrypter crypter, ParamNode node, Map<String, Variant> vars, ByteBuffer data, StringBuilder out, boolean isRaw) throws Exception
|
||||
{
|
||||
switch (node.getType())
|
||||
{
|
||||
case UCHAR:
|
||||
{
|
||||
short value = (byte) ByteReader.readChar(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Short.class));
|
||||
break;
|
||||
}
|
||||
case UBYTE:
|
||||
{
|
||||
int value = ByteReader.readUByte(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case SHORT:
|
||||
{
|
||||
short value = ByteReader.readShort(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Short.class));
|
||||
break;
|
||||
}
|
||||
case USHORT:
|
||||
{
|
||||
int value = ByteReader.readShort(data) & 65535;
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case UINT:
|
||||
{
|
||||
int value = ByteReader.readUInt(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case INT:
|
||||
{
|
||||
int value = ByteReader.readInt(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case CNTR:
|
||||
{
|
||||
int value = ByteReader.readCompactInt(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case UNICODE:
|
||||
{
|
||||
String str = ByteReader.readUtfString(data, isRaw);
|
||||
if (isRaw)
|
||||
{
|
||||
out.append(str);
|
||||
break;
|
||||
}
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append("[").append(str).append("]");
|
||||
}
|
||||
vars.put(node.getName(), new Variant(str, String.class));
|
||||
break;
|
||||
}
|
||||
case ASCF:
|
||||
{
|
||||
String str = ByteReader.readString(data, isRaw);
|
||||
if (isRaw)
|
||||
{
|
||||
out.append(str);
|
||||
break;
|
||||
}
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append("[").append(str).append("]");
|
||||
}
|
||||
vars.put(node.getName(), new Variant(str, String.class));
|
||||
break;
|
||||
}
|
||||
case DOUBLE:
|
||||
{
|
||||
double value = ByteReader.readDouble(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(new BigDecimal(Double.toString(value)).toPlainString());
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Double.class));
|
||||
break;
|
||||
}
|
||||
case FLOAT:
|
||||
{
|
||||
float value = ByteReader.readFloat(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(Float.valueOf(value), Float.class));
|
||||
break;
|
||||
}
|
||||
case LONG:
|
||||
{
|
||||
long value = ByteReader.readLong(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Long.class));
|
||||
break;
|
||||
}
|
||||
case RGBA:
|
||||
{
|
||||
String value = ByteReader.readRGBA(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, String.class));
|
||||
break;
|
||||
}
|
||||
case RGB:
|
||||
{
|
||||
String value = ByteReader.readRGB(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(value);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, String.class));
|
||||
break;
|
||||
}
|
||||
case HEX:
|
||||
{
|
||||
int value = ByteReader.readUByte(data);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
String hex = Integer.toHexString(value).toUpperCase();
|
||||
if (hex.length() == 1)
|
||||
{
|
||||
hex = "0" + hex;
|
||||
}
|
||||
out.append(hex);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(value, Integer.class));
|
||||
break;
|
||||
}
|
||||
case MAP_INT:
|
||||
{
|
||||
int index = ByteReader.readUInt(data);
|
||||
if (ConfigDebug.DAT_REPLACEMENT_NAMES)
|
||||
{
|
||||
String paramName = GameDataName.getInstance().getString(currentFile, crypter, index);
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(paramName);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(paramName, String.class));
|
||||
break;
|
||||
}
|
||||
if (!node.isIterator())
|
||||
{
|
||||
out.append(index);
|
||||
}
|
||||
vars.put(node.getName(), new Variant(index, Integer.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
362
L2ClientDat/java/com/l2jmobius/xml/DescriptorWriter.java
Normal file
362
L2ClientDat/java/com/l2jmobius/xml/DescriptorWriter.java
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.l2jmobius.clientcryptor.crypt.DatCrypter;
|
||||
import com.l2jmobius.config.ConfigDebug;
|
||||
import com.l2jmobius.data.GameDataName;
|
||||
import com.l2jmobius.util.ByteWriter;
|
||||
import com.l2jmobius.util.DebugUtil;
|
||||
import com.l2jmobius.util.Util;
|
||||
import com.l2jmobius.xml.exceptions.CycleArgumentException;
|
||||
import com.l2jmobius.xml.exceptions.PackDataException;
|
||||
|
||||
public class DescriptorWriter
|
||||
{
|
||||
private static final byte[] endFileBytes = new byte[]
|
||||
{
|
||||
12,
|
||||
83,
|
||||
97,
|
||||
102,
|
||||
101,
|
||||
80,
|
||||
97,
|
||||
99,
|
||||
107,
|
||||
97,
|
||||
103,
|
||||
101,
|
||||
0
|
||||
};
|
||||
private static final DescriptorWriter _instance = new DescriptorWriter();
|
||||
private static final Logger _log = LogManager.getLogger(DescriptorWriter.class);
|
||||
|
||||
public static DescriptorWriter getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public static byte[] parseData(File currentFile, DatCrypter crypter, Descriptor desc, String data) throws Exception
|
||||
{
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(data.length() / 2);
|
||||
if (desc.getFormat() != null)
|
||||
{
|
||||
data = desc.getFormat().encode(data);
|
||||
}
|
||||
if (desc.isRawData())
|
||||
{
|
||||
Buffer result = DescriptorWriter.parseNodeValue(currentFile, crypter, data, desc.getNodes().get(0), true);
|
||||
if (result != null)
|
||||
{
|
||||
stream.write((byte[]) result.array());
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.error("Failed to parse raw data.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(data.length() * 2);
|
||||
String lines = data.replace("\r\n", "\t");
|
||||
HashMap<ParamNode, Integer> counters = new HashMap<>();
|
||||
DescriptorWriter.packData(currentFile, crypter, buffer, lines, counters, new HashMap<String, String>(), new HashMap<ParamNode, String>(), desc.getNodes());
|
||||
try
|
||||
{
|
||||
buffer.flip();
|
||||
stream.write(ByteBuffer.allocate(buffer.limit()).put(buffer).array());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
DebugUtil.getLogger().error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (desc.isSafePackage())
|
||||
{
|
||||
stream.write(endFileBytes);
|
||||
}
|
||||
return stream.toByteArray();
|
||||
}
|
||||
|
||||
private static void packData(File currentFile, DatCrypter crypter, ByteBuffer buffer, String lines, Map<ParamNode, Integer> counters, Map<String, String> paramMap, Map<ParamNode, String> mapData, List<ParamNode> nodes) throws Exception
|
||||
{
|
||||
for (ParamNode node : nodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
String param;
|
||||
if (node.isIterator())
|
||||
{
|
||||
counters.put(node, buffer.position());
|
||||
continue;
|
||||
}
|
||||
if (node.getEntityType().isCycle())
|
||||
{
|
||||
if (!node.isNameHidden())
|
||||
{
|
||||
Pattern pattern = Pattern.compile("\\b" + node.getName().concat("_begin\\b(.*?)\\b").concat(node.getName()).concat("_end\\b"), 32);
|
||||
Matcher m = pattern.matcher(lines);
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
while (m.find())
|
||||
{
|
||||
list.add(m.group(1));
|
||||
}
|
||||
DescriptorWriter.writeSize(currentFile, crypter, buffer, counters, node, list.size());
|
||||
for (String str : list)
|
||||
{
|
||||
paramMap.putAll(Util.stringToMap(str));
|
||||
DescriptorWriter.packData(currentFile, crypter, buffer, str, counters, paramMap, mapData, node.getSubNodes());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
param = DescriptorWriter.getDataString(node, node.getName(), paramMap, mapData);
|
||||
if (param == null)
|
||||
{
|
||||
throw new Exception("Error getDataString == null node: " + node.getName());
|
||||
}
|
||||
if (param.isEmpty() || param.equals("{}"))
|
||||
{
|
||||
DescriptorWriter.writeSize(currentFile, crypter, buffer, counters, node, 0);
|
||||
continue;
|
||||
}
|
||||
List<String> subParams = Util.splitList(param);
|
||||
int cycleSize = subParams.size();
|
||||
if ((node.getSize() > 0) && (node.getSize() != cycleSize))
|
||||
{
|
||||
throw new Exception("Wrong static cycle count for cycle: " + node.getName() + " size: " + subParams.size() + " params: " + Arrays.toString(subParams.toArray()));
|
||||
}
|
||||
DescriptorWriter.writeSize(currentFile, crypter, buffer, counters, node, cycleSize);
|
||||
int nPramNode = 0;
|
||||
int nCycleNode = 0;
|
||||
for (ParamNode n : node.getSubNodes())
|
||||
{
|
||||
if (n.getEntityType().isCycle())
|
||||
{
|
||||
++nCycleNode;
|
||||
continue;
|
||||
}
|
||||
if (n.isIterator())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++nPramNode;
|
||||
}
|
||||
for (String subParam : subParams)
|
||||
{
|
||||
int paramIndex = 0;
|
||||
List<String> sub2Params = (nPramNode > 0) || (nCycleNode > 1) ? Util.splitList(subParam) : Collections.singletonList(subParam);
|
||||
for (ParamNode n : node.getSubNodes())
|
||||
{
|
||||
if (n.isIterator() || n.getEntityType().isConstant())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (paramIndex >= sub2Params.size())
|
||||
{
|
||||
throw new Exception("Wrong cycle param count for cycle: " + node.getName() + " paramIndex: " + paramIndex + " params: " + Arrays.toString(sub2Params.toArray()));
|
||||
}
|
||||
mapData.put(n, sub2Params.get(paramIndex++));
|
||||
}
|
||||
DescriptorWriter.packData(currentFile, crypter, buffer, lines, counters, paramMap, mapData, node.getSubNodes());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (node.getEntityType().isWrapper())
|
||||
{
|
||||
List<String> subParams = Util.splitList(DescriptorWriter.getDataString(node, node.getName(), paramMap, mapData));
|
||||
int paramIndex = 0;
|
||||
for (ParamNode n : node.getSubNodes())
|
||||
{
|
||||
if (n.isIterator() || n.getEntityType().isConstant())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mapData.put(n, subParams.get(paramIndex++));
|
||||
}
|
||||
DescriptorWriter.packData(currentFile, crypter, buffer, lines, counters, paramMap, mapData, node.getSubNodes());
|
||||
continue;
|
||||
}
|
||||
if (node.getEntityType().isVariable())
|
||||
{
|
||||
buffer.put((byte[]) DescriptorWriter.parseNodeValue(currentFile, crypter, DescriptorWriter.getDataString(node, node.getName(), paramMap, mapData), node, false).array());
|
||||
continue;
|
||||
}
|
||||
if (!node.getEntityType().isIf() || ((param = DescriptorWriter.getDataString(node, node.getParamIf(), paramMap, mapData)) == null) || !node.getValIf().equalsIgnoreCase(param))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DescriptorWriter.packData(currentFile, crypter, buffer, lines, counters, paramMap, mapData, node.getSubNodes());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PackDataException(e + "\r\n-node: " + node + "\r\n\tparam: " + paramMap.get(node.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Buffer parseNodeValue(File currentFile, DatCrypter crypter, String data, ParamNode node, boolean isRaw)
|
||||
{
|
||||
ParamType nodeType = node.getType();
|
||||
if (nodeType == null)
|
||||
{
|
||||
_log.error("Incorrect node type for node " + node);
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
switch (nodeType)
|
||||
{
|
||||
case UCHAR:
|
||||
{
|
||||
return ByteWriter.writeChar(Byte.parseByte(data));
|
||||
}
|
||||
case CNTR:
|
||||
{
|
||||
return ByteWriter.writeCompactInt(Integer.parseInt(data));
|
||||
}
|
||||
case UBYTE:
|
||||
{
|
||||
return ByteWriter.writeUByte(Short.parseShort(data));
|
||||
}
|
||||
case SHORT:
|
||||
{
|
||||
return ByteWriter.writeShort(Short.parseShort(data));
|
||||
}
|
||||
case USHORT:
|
||||
{
|
||||
return ByteWriter.writeUShort(Integer.parseInt(data));
|
||||
}
|
||||
case UINT:
|
||||
case INT:
|
||||
{
|
||||
return ByteWriter.writeInt(Integer.parseInt(data));
|
||||
}
|
||||
case UNICODE:
|
||||
{
|
||||
return ByteWriter.writeUtfString(isRaw ? data : data.substring(1, data.length() - 1), isRaw);
|
||||
}
|
||||
case ASCF:
|
||||
{
|
||||
return ByteWriter.writeString(isRaw ? data : data.substring(1, data.length() - 1), isRaw);
|
||||
}
|
||||
case DOUBLE:
|
||||
{
|
||||
return ByteWriter.writeDouble(Double.parseDouble(data));
|
||||
}
|
||||
case FLOAT:
|
||||
{
|
||||
return ByteWriter.writeFloat(Float.parseFloat(data));
|
||||
}
|
||||
case LONG:
|
||||
{
|
||||
return ByteWriter.writeLong(Long.parseLong(data));
|
||||
}
|
||||
case RGBA:
|
||||
{
|
||||
return ByteWriter.writeRGBA(data);
|
||||
}
|
||||
case RGB:
|
||||
{
|
||||
return ByteWriter.writeRGB(data);
|
||||
}
|
||||
case HEX:
|
||||
{
|
||||
return ByteWriter.writeByte((byte) (Integer.parseInt(data, 16) & 255));
|
||||
}
|
||||
case MAP_INT:
|
||||
{
|
||||
if (ConfigDebug.DAT_REPLACEMENT_NAMES)
|
||||
{
|
||||
return ByteWriter.writeInt(GameDataName.getInstance().getId(currentFile, crypter, node, data));
|
||||
}
|
||||
return ByteWriter.writeInt(Integer.parseInt(data));
|
||||
}
|
||||
}
|
||||
DebugUtil.getLogger().error("Unsupported primitive type " + (nodeType));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.error("Failed to parse value for node " + node + " data: " + data, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getDataString(ParamNode node, String name, Map<String, String> paramMap, Map<ParamNode, String> mapData)
|
||||
{
|
||||
if ((mapData != null) && mapData.containsKey(node))
|
||||
{
|
||||
return mapData.get(node);
|
||||
}
|
||||
return paramMap.get(name);
|
||||
}
|
||||
|
||||
private static void writeSize(File currentFile, DatCrypter crypter, ByteBuffer buffer, Map<ParamNode, Integer> counters, ParamNode node, int cycleSize) throws CycleArgumentException
|
||||
{
|
||||
if (!node.isSkipWriteSize() && (node.getSize() < 0))
|
||||
{
|
||||
ParamNode iterator = node.getTmpIterator();
|
||||
if (iterator == null)
|
||||
{
|
||||
counters.keySet().stream().filter(n -> n.getName().equals(node.getCycleName())).forEach(node::setTmpIterator);
|
||||
iterator = node.getTmpIterator();
|
||||
if (iterator == null)
|
||||
{
|
||||
throw new CycleArgumentException("Invalid argument [" + node.getName() + "] for cycle");
|
||||
}
|
||||
}
|
||||
Buffer buff = DescriptorWriter.parseNodeValue(currentFile, crypter, String.valueOf(cycleSize), iterator, false);
|
||||
int pos = counters.get(iterator);
|
||||
if (pos >= 0)
|
||||
{
|
||||
int rem = buffer.position();
|
||||
if (pos == rem)
|
||||
{
|
||||
buffer.put((byte[]) buff.array());
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] arrayNext = new byte[rem - pos];
|
||||
buffer.position(pos);
|
||||
buffer.get(arrayNext);
|
||||
buffer.position(pos);
|
||||
buffer.put((byte[]) buff.array());
|
||||
buffer.put(arrayNext);
|
||||
}
|
||||
counters.remove(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
189
L2ClientDat/java/com/l2jmobius/xml/ParamNode.java
Normal file
189
L2ClientDat/java/com/l2jmobius/xml/ParamNode.java
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ParamNode
|
||||
{
|
||||
private String _name;
|
||||
private int _size = -1;
|
||||
private boolean _hidden = false;
|
||||
private String _cycleName;
|
||||
private final ParamNodeType _entityType;
|
||||
private final ParamType _type;
|
||||
private List<ParamNode> _sub;
|
||||
private boolean _isIterator;
|
||||
private ParamNode _tmpIterator;
|
||||
private boolean _skipWriteSize;
|
||||
private String _paramIf;
|
||||
private String _valIf;
|
||||
|
||||
ParamNode(String name, ParamNodeType entityType, ParamType type)
|
||||
{
|
||||
_name = name;
|
||||
_entityType = entityType;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
public void setSize(int size)
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
void setIterator()
|
||||
{
|
||||
_isIterator = true;
|
||||
}
|
||||
|
||||
void setHidden()
|
||||
{
|
||||
_hidden = true;
|
||||
}
|
||||
|
||||
boolean isIterator()
|
||||
{
|
||||
return _isIterator && (_size < 0);
|
||||
}
|
||||
|
||||
boolean isNameHidden()
|
||||
{
|
||||
return _hidden;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
ParamNodeType getEntityType()
|
||||
{
|
||||
return _entityType;
|
||||
}
|
||||
|
||||
public ParamType getType()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
synchronized ParamNode copy()
|
||||
{
|
||||
ParamNode node = new ParamNode(getName(), getEntityType(), getType());
|
||||
if (isNameHidden())
|
||||
{
|
||||
node.setHidden();
|
||||
}
|
||||
if (isIterator())
|
||||
{
|
||||
node.setIterator();
|
||||
}
|
||||
node.setSkipWriteSize(isSkipWriteSize());
|
||||
node.setCycleName(getCycleName());
|
||||
if (getSubNodes() != null)
|
||||
{
|
||||
ArrayList<ParamNode> list = new ArrayList<>();
|
||||
for (ParamNode n : getSubNodes())
|
||||
{
|
||||
ParamNode copyN = n.copy();
|
||||
list.add(copyN);
|
||||
}
|
||||
node.addSubNodes(list);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
synchronized void addSubNodes(List<ParamNode> n)
|
||||
{
|
||||
if (_sub == null)
|
||||
{
|
||||
_sub = new ArrayList<>();
|
||||
}
|
||||
_sub.addAll(n);
|
||||
}
|
||||
|
||||
List<ParamNode> getSubNodes()
|
||||
{
|
||||
return _sub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return _name + "[" + (_entityType) + "][" + _cycleName + "][" + (_type) + "]";
|
||||
}
|
||||
|
||||
ParamNode getTmpIterator()
|
||||
{
|
||||
return _tmpIterator;
|
||||
}
|
||||
|
||||
void setTmpIterator(ParamNode tmpIterator)
|
||||
{
|
||||
_tmpIterator = tmpIterator;
|
||||
}
|
||||
|
||||
boolean isSkipWriteSize()
|
||||
{
|
||||
return _skipWriteSize;
|
||||
}
|
||||
|
||||
void setSkipWriteSize(boolean skipWrite)
|
||||
{
|
||||
_skipWriteSize = skipWrite;
|
||||
}
|
||||
|
||||
void setParamIf(String paramIf)
|
||||
{
|
||||
_paramIf = paramIf;
|
||||
}
|
||||
|
||||
void setValIf(String valIf)
|
||||
{
|
||||
_valIf = valIf;
|
||||
}
|
||||
|
||||
String getParamIf()
|
||||
{
|
||||
return _paramIf;
|
||||
}
|
||||
|
||||
String getValIf()
|
||||
{
|
||||
return _valIf;
|
||||
}
|
||||
|
||||
String getCycleName()
|
||||
{
|
||||
return _cycleName;
|
||||
}
|
||||
|
||||
void setCycleName(String cycleName)
|
||||
{
|
||||
_cycleName = cycleName;
|
||||
}
|
||||
}
|
55
L2ClientDat/java/com/l2jmobius/xml/ParamNodeType.java
Normal file
55
L2ClientDat/java/com/l2jmobius/xml/ParamNodeType.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
enum ParamNodeType
|
||||
{
|
||||
FOR,
|
||||
WRAPPER,
|
||||
CONSTANT,
|
||||
VARIABLE,
|
||||
IF;
|
||||
|
||||
private ParamNodeType()
|
||||
{
|
||||
}
|
||||
|
||||
boolean isCycle()
|
||||
{
|
||||
return this == FOR;
|
||||
}
|
||||
|
||||
public boolean isWrapper()
|
||||
{
|
||||
return this == WRAPPER;
|
||||
}
|
||||
|
||||
boolean isConstant()
|
||||
{
|
||||
return this == CONSTANT;
|
||||
}
|
||||
|
||||
boolean isVariable()
|
||||
{
|
||||
return this == VARIABLE;
|
||||
}
|
||||
|
||||
boolean isIf()
|
||||
{
|
||||
return this == IF;
|
||||
}
|
||||
}
|
42
L2ClientDat/java/com/l2jmobius/xml/ParamType.java
Normal file
42
L2ClientDat/java/com/l2jmobius/xml/ParamType.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
enum ParamType
|
||||
{
|
||||
UCHAR,
|
||||
CNTR,
|
||||
UBYTE,
|
||||
USHORT,
|
||||
SHORT,
|
||||
UINT,
|
||||
STRING,
|
||||
INT,
|
||||
UNICODE,
|
||||
ASCF,
|
||||
DOUBLE,
|
||||
FLOAT,
|
||||
LONG,
|
||||
RGBA,
|
||||
RGB,
|
||||
HEX,
|
||||
MAP_INT;
|
||||
|
||||
private ParamType()
|
||||
{
|
||||
}
|
||||
}
|
80
L2ClientDat/java/com/l2jmobius/xml/Variant.java
Normal file
80
L2ClientDat/java/com/l2jmobius/xml/Variant.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml;
|
||||
|
||||
public class Variant
|
||||
{
|
||||
private final Object _value;
|
||||
private final Class<?> _type;
|
||||
|
||||
Variant(Object value, Class<?> type)
|
||||
{
|
||||
_value = type.cast(value);
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public final boolean isInt()
|
||||
{
|
||||
return _type == Integer.class;
|
||||
}
|
||||
|
||||
public final boolean isShort()
|
||||
{
|
||||
return _type == Short.class;
|
||||
}
|
||||
|
||||
public final boolean isFloat()
|
||||
{
|
||||
return _type == Float.class;
|
||||
}
|
||||
|
||||
public final boolean isDouble()
|
||||
{
|
||||
return _type == Double.class;
|
||||
}
|
||||
|
||||
public final int getInt()
|
||||
{
|
||||
return (Integer) _value;
|
||||
}
|
||||
|
||||
public final short getShort()
|
||||
{
|
||||
return (Short) _value;
|
||||
}
|
||||
|
||||
public final float getFloat()
|
||||
{
|
||||
return ((Float) _value).floatValue();
|
||||
}
|
||||
|
||||
public double getDouble()
|
||||
{
|
||||
return (Double) _value;
|
||||
}
|
||||
|
||||
public long getLong()
|
||||
{
|
||||
return (Long) _value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString()
|
||||
{
|
||||
return String.valueOf(_value);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml.exceptions;
|
||||
|
||||
public class CycleArgumentException extends Exception
|
||||
{
|
||||
public CycleArgumentException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.xml.exceptions;
|
||||
|
||||
public class PackDataException extends Exception
|
||||
{
|
||||
public PackDataException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user