L2ClientDat decoder.
This commit is contained in:
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