|
You last visited: Today at 14:40
Advertisement
[TQ Binaries] Discussion and documentation
Discussion on [TQ Binaries] Discussion and documentation within the CO2 Private Server forum part of the Conquer Online 2 category.
01/15/2012, 01:44
|
#31
|
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
|
Quote:
Originally Posted by Kiyono
I noticed that Exodus had it right before you posted, also found master15's CoEmuv2 guide on this and I apparently already had the RedemptionCO source but it never even occurred to me that it might have TQ's npc system, lol Not sure what PMCO is? Link?
It could be me but 2031 doesn't have subtypes?

But since you say so, it's either the unknown or the npc_mode.
//edit For some reason, RedemptionCO's system and Exodus use exactly the same structs (ActionStruct/TaskStruct even the spaces are in the same place) so that either means that Exodus' system is based on this or vice versa but since RedemptionCO's implementation was flawed (what was wrong with it again?) Exodus' version should be flawed too.
|
The wiki isnt always correct sadly, somethings may be missing.
Essentially the action system should be treated as a series of If statements where by you progress by these statements being true/false through a tree.
That system doesnt do this correctly under a few circumstances which means that its entirely flawed, which results in a number of npcs having to be done manually (ie. not using the actionhandler at all for anything). As a result that means that the action system is being massively under utilised (something like 3% of the total number of actiontypes are handled). So thats basically whats wrong with it.
|
|
|
01/15/2012, 04:24
|
#32
|
elite*gold: 20
Join Date: Jan 2006
Posts: 890
Received Thanks: 241
|
Quote:
Originally Posted by Kiyono
//edit For some reason, RedemptionCO's system and Exodus use exactly the same structs (ActionStruct/TaskStruct even the spaces are in the same place) so that either means that Exodus' system is based on this or vice versa but since RedemptionCO's implementation was flawed (what was wrong with it again?) Exodus' version should be flawed too.
|
Part of it was based off ImmuneOnes implementation I had just taken it a lot further then he did.
Quote:
Originally Posted by Korvacs
The wiki isnt always correct sadly, somethings may be missing.
Essentially the action system should be treated as a series of If statements where by you progress by these statements being true/false through a tree.
That system doesnt do this correctly under a few circumstances which means that its entirely flawed, which results in a number of npcs having to be done manually (ie. not using the actionhandler at all for anything). As a result that means that the action system is being massively under utilised (something like 3% of the total number of actiontypes are handled). So thats basically whats wrong with it.
|
TQs NPC implementation was of the last things I was working on, so yeah it's not nearly near complete(however it is the furthest public implementation I've personally seen). But, that's why I had C# dialogs still in there.
|
|
|
01/15/2012, 10:40
|
#33
|
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
|
Quote:
Originally Posted by Korvacs
The wiki isnt always correct sadly, somethings may be missing.
Essentially the action system should be treated as a series of If statements where by you progress by these statements being true/false through a tree.
That system doesnt do this correctly under a few circumstances which means that its entirely flawed, which results in a number of npcs having to be done manually (ie. not using the actionhandler at all for anything). As a result that means that the action system is being massively under utilised (something like 3% of the total number of actiontypes are handled). So thats basically whats wrong with it.
|
I see, then do you also happen to know under which circumstances these flaws become noticeable? Depending on how much I care about those circumstances I might just implement RedemptionCO's system since I'm not striving for a perfect system.
|
|
|
01/15/2012, 10:59
|
#34
|
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
|
Quote:
Originally Posted by Kiyono
I see, then do you also happen to know under which circumstances these flaws become noticeable? Depending on how much I care about those circumstances I might just implement RedemptionCO's system since I'm not striving for a perfect system.
|
Well, if you look at the system and see how many npcs are handled separately, then you can probably work out that its pretty often.
|
|
|
01/15/2012, 11:12
|
#35
|
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
|
Well it's not that many, 11 NPCs + the warehouses, far from what I call many seeing the amount of NPCs there are and it seems that the only reason those are done in the source is because it's missing some handled action types unless I'm missing something of course. If that's all then I can just handle the action types (ok, it probably won't be that simple.) and make it work.
|
|
|
01/15/2012, 11:26
|
#36
|
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
|
The system has a flawed way of determining if it should use the NextID for the next action or the FailedID, so as a result some basic stuff works, but the rest of it doesnt, so saying "I can just handle the action types" is definitely not true in this case.
|
|
|
01/15/2012, 11:40
|
#37
|
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
|
Haven't looked that far yet. I'm going through the code while implementing it so I'll encounter it at some point and I'll think about it when it happens.
//edit Well I didn't exactly come far, server crashes when the npc option is something that is not 255.
//edit It probably has to do with how I did this:
Code:
public static void Text(GameClient Client, string str_text)
{
str_text = str_text.Replace("~", " ") + "\n";
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
NpcClickPacket* Reply;
Reply = NpcClickPacket.Create(ptr, str_text.Length);
Reply->ResponseID = NpcClickID.Dialogue;
Reply->Input = str_text;
Client.Send(Reply);
}
public static void Avatar(GameClient Client, ushort str_avatar)
{
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
NpcClickPacket* Reply;
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Avatar;
Reply->Avatar = str_avatar;
Client.Send(Reply);
}
public static void Link(GameClient Client, string str_text, byte link)
{
str_text = str_text.Replace("~", " ") + "\n";
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
NpcClickPacket* Reply;
Reply = NpcClickPacket.Create(ptr, str_text.Length);
Reply->ResponseID = NpcClickID.Option;
Reply->OptionID = link;
Reply->Input = str_text;
Client.Send(Reply);
}
public static void Input(GameClient Client, string str_text, byte link)
{
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
NpcClickPacket* Reply;
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Input;
Reply->MaxInputLength = (ushort)str_text.Length;
Reply->OptionID = link;
Client.Send(Reply);
}
public static void Finish(GameClient Client)
{
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
NpcClickPacket* Reply;
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Finish;
Reply->DontDisplay = false;
Client.Send(Reply);
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConquerServer_v2.Packet_Structures
{
public enum NpcClickID : byte
{
None = 0x00,
Dialogue = 0x01,
Option = 0x02,
Input = 0x03,
Avatar = 0x04,
Finish = 0x64,
DeleteGuildMember = 0x66
}
[StructLayout(LayoutKind.Explicit)]
/// <summary>
/// 0x7EF (Client->Server),
/// 0x7F0 (Client->Server)
///
/// </summary>
public unsafe struct NpcClickPacket
{
[FieldOffset(0)]
public ushort Size;
[FieldOffset(2)]
public ushort Type;
[FieldOffset(4)]
public uint NpcID;
[FieldOffset(8)]
public ushort Avatar;
[FieldOffset(8)]
public ushort MaxInputLength;
[FieldOffset(10)]
public byte OptionID;
[FieldOffset(11)]
public NpcClickID ResponseID;
[FieldOffset(12)]
public bool DontDisplay;
[FieldOffset(13)]
public byte InputLength;
[FieldOffset(14)]
private sbyte szInput;
public string Input
{
get { fixed (sbyte* ptr = &szInput) { return new string(ptr, 0, InputLength); } }
set { fixed (sbyte* ptr = &szInput) { value.CopyTo(ptr); } }
}
/// <summary>
/// Initializes a memory-block to be a NpcClickPacket, of type 0x7F0
/// </summary>
/// <param name="Ptr">The memory-block (make sure this has sufficient size for your string).</param>
/// <param name="TextLength">The length of your input string.</param>
/// <returns></returns>
public static NpcClickPacket* Create(void* Ptr, int TextLength)
{
NpcClickPacket* packet = (NpcClickPacket*)Ptr;
packet->Size = (ushort)(0x11 + TextLength);
packet->Type = 0x7F0;
packet->OptionID = 0xFF;
packet->DontDisplay = true;
packet->InputLength = (byte)TextLength;
return packet;
}
}
}
Original code in the source:
Code:
public static int Dialog(INpcPlayer Player, string[] Dlg)
{
const int BaseSize = 0x11;
byte* ptr = stackalloc byte[BaseSize];
int string_size = 0;
NpcClickPacket* Reply;
foreach (string parse_dlg in Dlg)
{
if (parse_dlg.StartsWith("AVATAR"))
{
string str_avatar = parse_dlg.Substring(7, parse_dlg.Length - 7);
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Avatar;
Reply->Avatar = ushort.Parse(str_avatar);
Player.Send(Reply);
}
else if (parse_dlg.StartsWith("TEXT"))
{
string str_text = parse_dlg.Substring(5, parse_dlg.Length - 5);
if (string_size < str_text.Length)
{
string_size = str_text.Length;
byte* temp = stackalloc byte[BaseSize + string_size];
ptr = temp;
}
Reply = NpcClickPacket.Create(ptr, str_text.Length);
Reply->ResponseID = NpcClickID.Dialogue;
Reply->Input = str_text;
Player.Send(Reply);
}
else if (parse_dlg.StartsWith("OPTION"))
{
string str_op_num = parse_dlg.Substring(6, parse_dlg.IndexOf(' ') - 6);
string str_op_text = parse_dlg.Substring(6 + str_op_num.Length + 1, parse_dlg.Length - 6 - str_op_num.Length - 1);
if (string_size < str_op_text.Length)
{
string_size = str_op_text.Length;
byte* temp = stackalloc byte[BaseSize + string_size];
ptr = temp;
}
Reply = NpcClickPacket.Create(ptr, str_op_text.Length);
Reply->ResponseID = NpcClickID.Option;
Reply->OptionID = (byte)short.Parse(str_op_num);
Reply->Input = str_op_text;
Player.Send(Reply);
}
else if (parse_dlg.StartsWith("INPUT"))
{
string str_in_num = parse_dlg.Substring(5, parse_dlg.IndexOf(' ') - 5);
string str_txt_len = parse_dlg.Substring(5 + str_in_num.Length + 1, parse_dlg.Length - 5 - str_in_num.Length - 1);
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Input;
Reply->MaxInputLength = ushort.Parse(str_txt_len);
Reply->OptionID = (byte)short.Parse(str_in_num);
Player.Send(Reply);
}
else if (parse_dlg.StartsWith("NOP"))
continue;
else
throw new ArgumentException("Failed to parse npc dialog statement `" + parse_dlg + "`");
}
Reply = NpcClickPacket.Create(ptr, 0);
Reply->ResponseID = NpcClickID.Finish;
Reply->DontDisplay = false;
Player.Send(Reply);
return 0;
}
I don't know how to use pointers >_>
|
|
|
01/15/2012, 21:16
|
#38
|
elite*gold: 0
Join Date: Jan 2008
Posts: 1,444
Received Thanks: 1,176
|
Quote:
Originally Posted by Kiyono
I don't know how to use pointers >_>
|
So, don't use them?
|
|
|
01/15/2012, 21:37
|
#39
|
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
|
From now on I won't.
|
|
|
01/19/2012, 01:19
|
#40
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,283
Received Thanks: 4,192
|
Quote:
Originally Posted by CptSky
So, don't use them?
|
Some people are terrified by pointers.
It still puzzles me (since to be considered as a basic programmer, you need to know pointers inside and out).
|
|
|
01/19/2012, 08:37
|
#41
|
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
|
Pointers are nothing hard, once you understand how they work.
Code:
ushort SomeValue = *(ushort*)(pointer + 10);
Meaning:
Code:
VALUE = USHORT VALUE OF (POINTER + OFFSET)
And same the other way around.
Code:
*(ushort*)(pointer + 10) = SomeValue;
Meaning:
Code:
USHORT VALUE OF (POINTER + OFFSET) = VALUE
Whatever.
Code:
int somevalue = 10;//declaring a variable
int* somepointer = &somevalue;//declaring a pointer of somevalue's address
int address = (int)somepointer;//Getting the address of somepointer
int value = *somepointer;//Getting the value of somepointer
|
|
|
01/19/2012, 10:00
|
#42
|
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
|
Can anyone help me with this?
I figured i would ask in the EO section since its the EO source im looking at but it was a pointless exercise....
|
|
|
01/19/2012, 16:15
|
#43
|
elite*gold: 0
Join Date: Jun 2005
Posts: 692
Received Thanks: 353
|
Quote:
Originally Posted by Korvacs
Can anyone help me with this?
I figured i would ask in the EO section since its the EO source im looking at but it was a pointless exercise....
|
It's labeled that in EO, but it's something different in CO.
Code:
enum ENUM_MAPTYPE {
MAPTYPE_NORMAL = 0x0000, // 00
MAPTYPE_PKFIELD = 0x0001, // 01
MAPTYPE_CHGMAP_DISABLE = 0x0002, // 02 // magic call team member
MAPTYPE_RECORD_DISABLE = 0x0004, // 04
MAPTYPE_PK_DISABLE = 0x0008, // 08
MAPTYPE_BOOTH_ENABLE = 0x0010, // 16
MAPTYPE_TEAM_DISABLE = 0x0020, // 32
MAPTYPE_TELEPORT_DISABLE = 0x0040, // 64 // chgmap by action
MAPTYPE_SYN_MAP = 0x0080, // 128
MAPTYPE_PRISON_MAP = 0x0100, // 256
MAPTYPE_WING_DISABLE = 0x0200, // 512 // bowman fly disable
MAPTYPE_FAMILY = 0x0400, // 1024
MAPTYPE_MINEFIELD = 0x0800, // 2048
MAPTYPE_CALLNEWBIE_DISABLE = 0x1000, // 4096
MAPTYPE_REBORN_NOW_ENABLE = 0x2000, // 8192
MAPTYPE_NEWBIE_PROTECT = 0x4000, // 16384
}
That should make a bit more sense.
|
|
|
01/19/2012, 16:22
|
#44
|
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
|
Yeah i know what it does and how it works, but i dont know what it does. For example we have one that disables PK which is pretty obvious, this is part of the battle system for eo and doesnt really have any real explanation as to what it actually does, except that i know that it acts sort of like arena in that it determines if you receive a flashing name or not. So i need to know what it does....i thought that was clear in my thread
|
|
|
01/19/2012, 16:48
|
#45
|
elite*gold: 0
Join Date: Jan 2008
Posts: 1,444
Received Thanks: 1,176
|
Quote:
Originally Posted by Korvacs
Yeah i know what it does and how it works, but i dont know what it does. For example we have one that disables PK which is pretty obvious, this is part of the battle system for eo and doesnt really have any real explanation as to what it actually does, except that i know that it acts sort of like arena in that it determines if you receive a flashing name or not. So i need to know what it does....i thought that was clear in my thread 
|
MAPTYPE_NEWBIE_PROTECT (DEAD_ISLAND in EO) is the newbie protection on map. By memory, it was lvl 26- that was protected from being killed by other people.
|
|
|
 |
|
Similar Threads
|
[Moved] Binaries vs C# sources discussion and donation debate (aka the mods are mean)
01/13/2012 - CO2 Private Server - 37 Replies
Note: This was spawned in response to various server discussions in another thread.. I felt it was going extremly off topic. It's NOT designed as an attack and (at least from my standpoint) has nothing to do with Zero or his server.
That being said I felt that deleting 10-15 posts that broke no rule (besides being a tangent from original topic) would be unfair to members and I feel that the conversation is at least somewhat relevant to the forum.
</disclaimer>
<In regards to pvp...
|
New packets documentation website
11/30/2011 - SRO Coding Corner - 1 Replies
I have opened new website where you will find packets + tools + mini emulator(open source) for beginners and advance developers wich will let you research on packets. For now there is not much on the website, i will public more packets every day. I posted it in new thread because many peoples may looking for knowledge here. I hope you will like it.
website adres: SSE packets center
http://img192.imageshack.us/img192/7762/strea.jpg
|
Request: MXI usage documentation (no PXI
08/13/2010 - Final Fantasy XI - 0 Replies
I know that MXI and (PXI svn change documentation only!!!) data is becoming hard to find let alone obtain.
I wanted to know if anyone has any documentation from MXI
(that you will post, so we can download it)
mainly the svn stuff
or usage of MXI
theres plenty of PXI stuff, so please don't post it here
|
All times are GMT +1. The time now is 14:41.
|
|