NetPro: Packet Analysis and Visualization tool
Forum rules
READ NOW: L2j Forums Rules of Conduct
READ NOW: L2j Forums Rules of Conduct
-
- Posts: 39
- Joined: Wed Feb 19, 2014 12:13 pm
Re: NetPro: Packet Analysis and Visualization tool
Do someone have a script to get spawnlist from packet NpcInfo/ExNpcInfo ?
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
This will SPECIFICALLY extract all NON-MOVING NPC spawn locations and yaws (headings). Of course, some mutually interacting NPCs seem to change their heading from time to time (I think that's a part of their AI script). However, these are generally only in some special locations, even though there is one or two in the new TI).
Makes use on script aliases already present within packet definitions (personally I last tested this back in Valiance, before the incremental definition loading; but I hope the ertheian definitions have also had the missing aliases added by now).
You may not use this script to gather monster locations, basically because they never respawn in the same spot on official servers.
P.S. This was made on request quite some time ago, so you might need to tune the output generation to suit your own needs.
Makes use on script aliases already present within packet definitions (personally I last tested this back in Valiance, before the incremental definition loading; but I hope the ertheian definitions have also had the missing aliases added by now).
You may not use this script to gather monster locations, basically because they never respawn in the same spot on official servers.
Code: Select all
/*
* Copyright (c) 2012-2015, RaveN Network INC. and/or its affiliates. All rights reserved.
* RAVEN NETWORK INC. PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
* Licensed Materials - Property of RaveN Network INC.
* Restricted Rights - Use, duplication or disclosure restricted.
*/
package internal.generator;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import javolution.util.FastMap;
import org.apache.commons.lang3.StringUtils;
import util.packet.CommonPacketSender;
import net.l2emuproject.proxy.network.game.client.L2GameClient;
import net.l2emuproject.proxy.network.game.server.L2GameServer;
import net.l2emuproject.proxy.network.meta.RandomAccessMMOBuffer;
import net.l2emuproject.proxy.network.meta.field.EnumeratedPayloadField;
import net.l2emuproject.proxy.script.ScriptFieldAlias;
import net.l2emuproject.proxy.script.game.InteractiveChatCommands;
import net.l2emuproject.proxy.script.game.PpeEnabledGameScript;
import net.l2emuproject.proxy.script.packets.InvalidPacketWriterArgumentsException;
import net.l2emuproject.proxy.state.entity.ObjectInfo;
import net.l2emuproject.proxy.state.entity.ObjectLocation;
import net.l2emuproject.proxy.state.entity.cache.ObjectInfoCache;
import net.l2emuproject.proxy.state.entity.context.ICacheServerID;
import net.l2emuproject.proxy.state.entity.type.NonPlayerControllable;
import net.l2emuproject.proxy.state.entity.type.ObjectType;
import net.l2emuproject.proxy.ui.savormix.io.base.IOConstants;
import net.l2emuproject.script.util.HasScriptDependencies;
import net.l2emuproject.util.L2Collections;
import net.l2emuproject.util.concurrent.L2ThreadPool;
import net.l2emuproject.util.logging.L2Logger;
/**
* A basic spawn list generator for non-moving NPCs.
* <B>The operator of this script must ensure</B> that the state is only saved after it was made sure
* that all NPC walkers that ever were in knownlist range have moved at least once (or have attacked
* something).
* However, alternative measures should be taken to ensure that stationary guards were not distracted
* by aggressive or negative reputation players.
*
* @author _dev_
*/
@HasScriptDependencies("util.packet.CommonPacketSender")
public class FixedSpawnGenerator extends PpeEnabledGameScript implements InteractiveChatCommands, IOConstants
{
static final L2Logger LOG = L2Logger.getLogger(FixedSpawnGenerator.class);
static final Pattern NAME_TRIM = Pattern.compile("(?:[0-9]+: )|(?:\\[not named in client\\])|(?: \\[NPC\\])");
@ScriptFieldAlias
private static final String NPC_OID = "fspawn_gen_npc_oid";
@ScriptFieldAlias
private static final String NPC_ATTACKABLE = "fspawn_gen_npc_atk";
@ScriptFieldAlias
private static final String WALKER_OID = "fspawn_walker_oid";
static final Path OUTPUT_ROOT = DATA_MINING_DIRECTORY.resolve("spawn_data");
//private final FastMap<ICacheServerID, ServerSpawns> _data;
// mapping by client results in better interactivity
private final FastMap<L2GameClient, ServerSpawns> _data;
private volatile Future<?> _saveTask;
/** Constructs this script. */
public FixedSpawnGenerator()
{
//_data = new FastMap<ICacheServerID, ServerSpawns>().setShared(true);
_data = new FastMap<L2GameClient, ServerSpawns>().setShared(true);
}
@Override
public void handleDisconnection(L2GameClient client)
{
_data.remove(client);
}
@Override
public void handleClientPacket(final L2GameClient client, L2GameServer server, RandomAccessMMOBuffer buf) throws RuntimeException
{
String msg = buf.readFirstString(CHAT_COMMAND);
if ("\\\\fs_reset".equals(msg))
{
_data.put(client, new ServerSpawns());
try
{
CommonPacketSender.sendChatMessage(client, 5, "SYS", "Spawn generator state cleared.");
}
catch (InvalidPacketWriterArgumentsException e)
{
LOG.warn("", e);
}
return;
}
if (!"\\\\fs_save".equals(msg))
return;
if (_saveTask != null && !_saveTask.isDone())
{
try
{
CommonPacketSender.sendChatMessage(client, 5, "SYS", "A state save is already in progress.");
}
catch (InvalidPacketWriterArgumentsException e)
{
LOG.warn("", e);
}
return;
}
final ICacheServerID context = getEntityContext(server);
//final ServerSpawns spawns = _data.get(context);
final ServerSpawns spawns = _data.get(client);
if (spawns == null)
return;
try
{
CommonPacketSender.sendChatMessage(client, 5, "SYS", "Saving " + spawns._fixedSpawns.size() + " static NPC spawns to disk.");
}
catch (InvalidPacketWriterArgumentsException e)
{
LOG.warn("", e);
// not a big deal if no message was sent; continue
}
_saveTask = L2ThreadPool.submitLongRunning(new Runnable()
{
@Override
public void run()
{
final Path dir = OUTPUT_ROOT.resolve(String.valueOf(client.getProtocol().getVersion()));
try
{
Files.createDirectories(dir);
try (final BufferedWriter bw = Files.newBufferedWriter(dir.resolve("walkers_" + System.currentTimeMillis() + ".txt"), Charset.forName("UTF-8")))
{
for (final Integer npc : spawns._walkerNPCs)
bw.append(String.valueOf(npc)).append("\r\n");
}
try (final BufferedWriter bw = Files.newBufferedWriter(dir.resolve("spawns_" + System.currentTimeMillis() + ".xml"), Charset.forName("UTF-8")))
{
bw.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("\r\n\r\n");
bw.append("<list xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"../../templates/spawnlist.xsd\">");
bw.append("\r\n");
final Map<Integer, String> npcNames = new HashMap<>();
final Map<Integer, Set<ObjectLocation>> locByNPC = new TreeMap<>();
final ObjectInfoCache cache = ObjectInfoCache.getInstance();
for (final Entry<Integer, ObjectLocation> e : spawns._fixedSpawns.entrySet())
{
final ObjectInfo oi = cache.getOrAdd(e.getKey(), context);
final ObjectLocation initial = e.getValue(), current = oi.getLocation();
if (!initial.equals(current))
{
if (initial.getX() != current.getX() || initial.getY() != current.getY() || initial.getZ() != current.getZ())
{
LOG.info("OH NO IT'S A WALKER " + oi);
LOG.info("Current: " + current + ", old: " + initial);
}
else
LOG.info("Heading mismatch! Initial: " + initial.getHeading() + ", current: " + current.getHeading() + " for " + oi);
continue;
}
final ObjectType type = oi.getType();
if (!(type instanceof NonPlayerControllable))
{
LOG.info("OH NO IT'S NOT A NPC " + oi);
continue;
}
final Integer npc = ((NonPlayerControllable)type).getTemplateID();
if (spawns._walkerNPCs.contains(npc))
continue;
if (!npcNames.containsKey(npc))
npcNames.put(npc, NAME_TRIM.matcher(oi.toString()).replaceAll(""));
Set<ObjectLocation> locations = locByNPC.get(npc);
if (locations == null)
{
locations = new TreeSet<>(new LocationOrder());
locByNPC.put(npc, locations);
}
locations.add(initial);
}
for (final Entry<Integer, Set<ObjectLocation>> e : locByNPC.entrySet())
{
bw.append("\t<spawn npcId=\"").append(e.getKey().toString()).append("\">\r\n");
final String name = npcNames.get(e.getKey());
if (!StringUtils.isEmpty(name))
bw.append("\t\t<!-- ").append(name).append(" -->\r\n");
for (final ObjectLocation loc : e.getValue())
{
bw.append("\t\t<location x=\"").append(String.valueOf(loc.getX())).append("\" y=\"");
bw.append(String.valueOf(loc.getY())).append("\" z=\"").append(String.valueOf(loc.getZ()));
bw.append("\" heading=\"").append(String.valueOf(loc.getHeading())).append("\" />\r\n");
}
bw.append("\t</spawn>\r\n");
}
bw.append("</list>\r\n");
}
}
catch (IOException e)
{
LOG.error("Cannot save NPC spawns.", e);
return;
}
try
{
CommonPacketSender.sendChatMessage(client, 5, "SYS", "NPC spawns saved to disk.");
}
catch (InvalidPacketWriterArgumentsException e)
{
LOG.warn("", e);
// not a big deal if no message was sent
}
}
});
}
@Override
public void handleServerPacket(L2GameClient client, L2GameServer server, RandomAccessMMOBuffer buf) throws RuntimeException
{
removeWalker:
{
final EnumeratedPayloadField oid = buf.getSingleFieldIndex(WALKER_OID);
if (oid == null)
break removeWalker;
final ICacheServerID context = getEntityContext(server);
//ServerSpawns spawns = _data.get(context);
ServerSpawns spawns = _data.get(client);
if (spawns == null)
spawns = L2Collections.putIfAbsent(_data, client, new ServerSpawns());
// spawns = L2Collections.putIfAbsent(_data, context, new ServerSpawns());
final Integer objectID = buf.readInteger32(oid);
if (spawns._fixedSpawns.remove(objectID) == null)
return;
final ObjectInfo oi = ObjectInfoCache.getInstance().getOrAdd(objectID, context);
final ObjectType type = oi.getType();
if (!(type instanceof NonPlayerControllable))
return;
final NonPlayerControllable template = (NonPlayerControllable)type;
spawns._walkerNPCs.add(template.getTemplateID());
return;
}
addSpawn:
{
final EnumeratedPayloadField oid = buf.getSingleFieldIndex(NPC_OID);
final EnumeratedPayloadField atk = buf.getSingleFieldIndex(NPC_ATTACKABLE);
if (oid == null || atk == null)
break addSpawn;
final ICacheServerID context = getEntityContext(server);
//ServerSpawns spawns = _data.get(context);
ServerSpawns spawns = _data.get(client);
if (spawns == null)
spawns = L2Collections.putIfAbsent(_data, client, new ServerSpawns());
// spawns = L2Collections.putIfAbsent(_data, context, new ServerSpawns());
final Integer objectID = buf.readInteger32(oid);
final boolean hostile = buf.readInteger32(atk) != 0;
if (hostile || !spawns._ignoredOIDs.add(objectID))
return;
final ObjectInfo oi = ObjectInfoCache.getInstance().getOrAdd(objectID, context);
if (!(oi.getType() instanceof NonPlayerControllable))
return;
if (spawns._fixedSpawns.remove(objectID) != null)
{
LOG.info("Constraint violation for " + oi);
return;
}
spawns._fixedSpawns.put(objectID, oi.getLocation());
return;
}
}
@Override
public String getName()
{
return "NPC spawn gen (static)";
}
private static final class LocationOrder implements Comparator<ObjectLocation>
{
LocationOrder()
{
}
@Override
public int compare(ObjectLocation o1, ObjectLocation o2)
{
int diff = o1.getZ() - o2.getZ();
if (diff != 0)
return diff;
diff = o1.getY() - o2.getY();
if (diff != 0)
return diff;
diff = o1.getX() - o2.getX();
if (diff != 0)
return diff;
diff = o1.getHeading() - o2.getHeading();
if (diff != 0)
return diff;
return 0;
}
}
private static final class ServerSpawns
{
final Set<Integer> _ignoredOIDs;
final Map<Integer, ObjectLocation> _fixedSpawns;
final Set<Integer> _walkerNPCs;
ServerSpawns()
{
_fixedSpawns = new FastMap<Integer, ObjectLocation>().setShared(true);
_ignoredOIDs = new CopyOnWriteArraySet<Integer>();
_walkerNPCs = new CopyOnWriteArraySet<Integer>();
}
}
}
-
- Posts: 39
- Joined: Wed Feb 19, 2014 12:13 pm
Re: NetPro: Packet Analysis and Visualization tool
Well, thank you. I will try to use it
upd:
After download new version, i dont see GameSever connection in NA
upd:
After download new version, i dont see GameSever connection in NA
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
Thanks for the report.ChaosPaladin wrote:Well, thank you. I will try to use it
upd:
After download new version, i dont see GameSever connection in NA
I could not reproduce this on my development machine, but I use a relatively large serviceconfig.xml there. After opening NP on another computer with the default config I could reproduce this issue.
Until the next release, please change the default gameWorldSocket to
Code: Select all
<gameWorldSocket ip="127.0.0.1" port="7776" />
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
A new release is now available, this time with JavaDoc (see the original post).
This marks yet another step towards preparing NP for open source. Slowly getting there
P.S. Ironically, JavaDoc for -commons-scripts is not provided. The component will be open sourced soon (luckily, it's a standalone).
P.P.S. JavaDoc for -commons is not provided. This component is one of the larger issues in the way of making NP open source, and I do not have a suitable way to deal with it for now.
This marks yet another step towards preparing NP for open source. Slowly getting there
P.S. Ironically, JavaDoc for -commons-scripts is not provided. The component will be open sourced soon (luckily, it's a standalone).
P.P.S. JavaDoc for -commons is not provided. This component is one of the larger issues in the way of making NP open source, and I do not have a suitable way to deal with it for now.
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
A new [pre]release is now out, mainly IO support with some minor fixes. Still have to deal with 1.5 (yes, that's one and a half) dependencies before it will be possible to opensource the application. I already know what will be needed and what will have to change once things are set in motion, so it should not take too long after that. I'll keep you guys notified about any further developments.
In the meantime, I'll still be providing routine releases such as this one. Have fun
In the meantime, I'll still be providing routine releases such as this one. Have fun
-
- Posts: 10
- Joined: Sun Apr 27, 2014 12:17 pm
Re: NetPro: Packet Analysis and Visualization tool
Hi.
In Attachement I added diff for: CharacterSelectionInfo.xml
In Attachement I added diff for: CharacterSelectionInfo.xml
You do not have the required permissions to view the files attached to this post.
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
Thank you, I'll make sure to apply it to all versions of this packet starting from the first client with armor enchant glows.michael1414 wrote:Hi.
In Attachement I added diff for: CharacterSelectionInfo.xml
-
- Posts: 10
- Joined: Sun Apr 27, 2014 12:17 pm
Re: NetPro: Packet Analysis and Visualization tool
Hi.
Next changes for: CharacterSelectionInfo.xml
PS: Would be chance to add this xml files to github or any other server ? Would be much easier to making changes in that files.
Next changes for: CharacterSelectionInfo.xml
PS: Would be chance to add this xml files to github or any other server ? Would be much easier to making changes in that files.
You do not have the required permissions to view the files attached to this post.
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
See https://bitbucket.org/_dev_/netpro or directly here.michael1414 wrote:Hi.
Next changes for: CharacterSelectionInfo.xml
PS: Would be chance to add this xml files to github or any other server ? Would be much easier to making changes in that files.
-
- Posts: 2
- Joined: Tue Mar 31, 2009 6:53 pm
Re: NetPro: Packet Analysis and Visualization tool
Code: Select all
INFO [2015-06-30 01:32:41.167 +0800] ShutdownManager: ShutdownHook: Initialized.
INFO [2015-06-30 01:32:41.167 +0800] DeadlockDetector: DeadlockDetector: Initialized.
INFO [2015-06-30 01:32:41.213 +0800] NetProScriptLog: Initialized scripts -> script.cache
INFO [2015-06-30 01:32:41.213 +0800] NetProScriptLog: Loading compiled script cache from script.cache…
INFO [2015-06-30 01:32:41.213 +0800] NetProScriptLog: [VFS] script.cache is not present.
INFO [2015-06-30 01:32:41.213 +0800] VersionnedPacketTable: Loading packet declarations…
INFO [2015-06-30 01:32:41.291 +0800] VersionnedPacketTable: Total: 504 client packets and 722 server packets.
INFO [2015-06-30 01:32:41.291 +0800] VersionnedPacketTable: Loading protocol declarations…
INFO [2015-06-30 01:32:41.307 +0800] VersionnedPacketTable: Total: 2 login protocols and 54 game protocols.
INFO [2015-06-30 01:32:41.307 +0800] VersionnedPacketTable: Loading packet definitions…
INFO [2015-06-30 01:32:41.307 +0800] VersionnedPacketTable: Loading login packets…
INFO [2015-06-30 01:32:41.307 +0800] VersionnedPacketTable: Prelude PTS declares 3 client and 10 server packets.
SEVERE [2015-06-30 01:32:41.323 +0800] proxy.ui.savormix.io.EndpointPacketLoader.toStructureElement(): RequestLogin
net.l2emuproject.proxy.network.meta.exception.InvalidFieldValueInterpreterException: null(ASCII) cannot be cast to net.l2emuproject.proxy.network.meta.FieldValueInterpreter
at net.l2emuproject.proxy.network.meta.container.MetaclassRegistry.getInterpreter(MetaclassRegistry.java:186)
at net.l2emuproject.proxy.ui.savormix.io.EndpointPacketLoader.toStructureElement(EndpointPacketLoader.java:234)
at net.l2emuproject.proxy.ui.savormix.io.EndpointPacketLoader.childrenOf(EndpointPacketLoader.java:172)
at net.l2emuproject.proxy.ui.savormix.io.EndpointPacketLoader.visitFile(EndpointPacketLoader.java:140)
at net.l2emuproject.proxy.ui.savormix.io.EndpointPacketLoader.visitFile(EndpointPacketLoader.java:69)
at java.nio.file.Files.walkFileTree(Unknown Source)
at java.nio.file.Files.walkFileTree(Unknown Source)
at net.l2emuproject.proxy.ui.savormix.io.VersionnedPacketTable.loadConfig(VersionnedPacketTable.java:422)
at net.l2emuproject.proxy.ui.savormix.io.VersionnedPacketTable.<init>(VersionnedPacketTable.java:85)
at net.l2emuproject.proxy.ui.savormix.io.VersionnedPacketTable$SingletonHolder.<clinit>(VersionnedPacketTable.java:753)
at net.l2emuproject.proxy.ui.savormix.io.VersionnedPacketTable.getInstance(VersionnedPacketTable.java:748)
at net.l2emuproject.proxy.ui.savormix.loader.Loader$$Lambda$20/1032616650.run(Unknown Source)
at net.l2emuproject.proxy.L2Proxy.main(L2Proxy.java:91)
at net.l2emuproject.proxy.ui.savormix.loader.Loader.main(Loader.java:265)
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
Code: Select all
NetProScriptLog: Loading compiled script cache from script.cache…
NetProScriptLog: [VFS] script.cache is not present.
- run NetPro via a JDK executable*
- put this precompiled cache in the main directory
P.S. I added the precompiled script cache as an optional download. Might have to start add version information in the filename for subsequent releases (for now, NP is on a monthly release cycle).
-
- Posts: 2
- Joined: Tue Mar 31, 2009 6:53 pm
Re: NetPro: Packet Analysis and Visualization tool
(Sorry for my english)SaveGame wrote:Yeah, I am aware that the 1.0 release did not include a precompiled script cache. Therefore, you must either:Code: Select all
NetProScriptLog: Loading compiled script cache from script.cache… NetProScriptLog: [VFS] script.cache is not present.
- run NetPro via a JDK executable*
- put this precompiled cache in the main directory
Thank you. put your script.cache, It started normally
Then I delete your script.cache, and edit NetPro_win.bat
edit @start /ABOVENORMAL javaw.exe to "C:\Program Files\Java\jdk1.8.0_xxx\bin\javaw.exe"
It started normally too. log:
Code: Select all
NFO [2015-06-30 03:07:41.719 +0800] ShutdownManager: ShutdownHook: Initialized.
INFO [2015-06-30 03:07:41.719 +0800] DeadlockDetector: DeadlockDetector: Initialized.
INFO [2015-06-30 03:07:41.797 +0800] NetProScriptLog: Initialized scripts -> script.cache
INFO [2015-06-30 03:07:41.797 +0800] NetProScriptLog: Loading compiled script cache from script.cache…
INFO [2015-06-30 03:07:41.797 +0800] NetProScriptLog: [VFS] script.cache is not present.
INFO [2015-06-30 03:07:41.797 +0800] NetProScriptLog: Traversing scripts…
INFO [2015-06-30 03:07:41.797 +0800] NetProScriptLog: Indexing scripts in scripts…
INFO [2015-06-30 03:07:41.812 +0800] NetProScriptLog: Indexing scripts in scripts\condition…
INFO [2015-06-30 03:07:41.812 +0800] NetProScriptLog: Indexing scripts in scripts\condition\airship…
INFO [2015-06-30 03:07:41.812 +0800] NetProScriptLog: Indexing scripts in scripts\condition\equip…
INFO [2015-06-30 03:07:41.812 +0800] NetProScriptLog: Indexing scripts in scripts\condition\event…
-
- Posts: 5
- Joined: Sun Jul 12, 2015 11:31 pm
Re: NetPro: Packet Analysis and Visualization tool
Duplicate File:
1.1\config\packets\gracia_final\client\RequestRecipeShopMakeItem.xml
packet id="CM_REQ_RECIPE_SHOP_MAKE_DO"
But already there have a
1.1\config\packets\c2_age_of_splendor\client\RequestRecipeShopMakeDo.xml
packet id="CM_REQ_RECIPE_SHOP_MAKE_DO"
1.1\config\packets\gracia_final\client\RequestRecipeShopMakeItem.xml
packet id="CM_REQ_RECIPE_SHOP_MAKE_DO"
But already there have a
1.1\config\packets\c2_age_of_splendor\client\RequestRecipeShopMakeDo.xml
packet id="CM_REQ_RECIPE_SHOP_MAKE_DO"
-
- Posts: 121
- Joined: Thu Oct 30, 2014 9:54 pm
Re: NetPro: Packet Analysis and Visualization tool
Hi,rocknowx wrote:Duplicate File: RequestRecipeShopMakeItem.xml
actually, it isn't a duplicate in this case. The filename was (inadvertently) not updated to match the actual packet name, but that's pretty much it.
You should take note of XML comments in these definition files, they would tell you why those files are kept in this case.
Let me explain the incremental loading for CM_REQ_RECIPE_SHOP_MAKE_DO:
1. Initially, the packet was introduced in C2 (both opcode_mapping.xml and /client/RequestRecipeShopMakeDo.xml):
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<packet id="CM_REQ_RECIPE_SHOP_MAKE_DO" xmlns="http://www.l2emu-unique.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.l2emu-unique.net ../../../schemata/packet.xsd">
<dword alias="Manufacturer's OID" type="ObjectID" />
<dword alias="Recipe" type="Recipe" />
</packet>
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!-- Added manufacturing price DWORD at the end of packet -->
<packet id="CM_REQ_RECIPE_SHOP_MAKE_DO" xmlns="http://www.l2emu-unique.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.l2emu-unique.net ../../../schemata/packet.xsd">
<dword alias="Manufacturer's OID" type="ObjectID" />
<dword alias="Recipe" type="Recipe" />
<!-- NEW -->
<dword alias="Price" />
</packet>
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!-- Manufacturing price is now a QWORD -->
<packet id="CM_REQ_RECIPE_SHOP_MAKE_DO" xmlns="http://www.l2emu-unique.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.l2emu-unique.net ../../../schemata/packet.xsd">
<dword alias="Manufacturer's OID" type="ObjectID" />
<dword alias="Recipe" type="Recipe" />
<qword alias="Price" /> <!-- NEW -->
</packet>
Regards,
SaveGame