Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Private Server > CO2 PServer Guides & Releases
You last visited: Today at 11:47

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[LazyRelease] Log python npc scripts from TQ!

Discussion on [LazyRelease] Log python npc scripts from TQ! within the CO2 PServer Guides & Releases forum part of the CO2 Private Server category.

Reply
 
Old   #1
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
[LazyRelease] Log python npc scripts from TQ!

Ok so I posted about this ages ago but realized after being msg'd on youtube that I've never actually posted the code to do this...

As many of you know, I never bothered adding npc scripts for well... any npcs in the hellmouth source...


THIS WILL ONLY LOG NPC SPAWN LOCATIONS AND THE FIRST PAGE OF TEXT/OPTIONS WHEN YOU TALK TO THEM!!!


I've also been trying to encourage people to use the damn external python scripts but so far they haven't taken much of an interest... well here's something that may change that for some people.


What do I need?

This is for use with my proxy release which can be found

Set up should be rather simple but I'll go over it very quickly here...

-Edit conquer loader to use the ports in the program.cs (namely 5001 or 5002 for login port 5000 for game port + a local hamachi ip. DO NOT USE 127.0.0.1 OR YOU WILL CRASH THE CLIENT)

Port 5001 = new server groups (generally left side of groups)
Port 5002 = old server groups (generally right side... IE: wild kingdom and such)

Now, you'll want to edit your settings.txt file in the proxy bin/debug folder to be using the correct settings.


THIS WILL CAUSE THE DATABASE TO BE USED SO PLEASE ENSURE YOU'VE RUN THE DATABASE BACKUP (make sure innodb is enabled... not sure if i'm using it in this db though) AND THE MYSQL SETTINGS ARE CORRECT IN THE SETTINGS.TXT FILE



Now... open up the proxy source code and follow my lead.

Not strongly needed but I added it for the hell of it and so I could see what I was missing...

Program.cs

anywhere near the top (since ppl suck lets just say right above 'DynaMaps')

Code:
public static List<uint> npcsInDatabase = new List<uint>();
Right below " Wha.Start();" place

Code:
                Database.GetNpcs();
Database.cs

Code:
 public static void AddNpc(Npc S)
        {
            MySqlCommand cmd = new MySqlCommand(MySqlCommandType.INSERT);
            cmd.Insert("npcs")
                .Insert("UID", S.UID)
                .Insert("ID", S.ID)
                .Insert("X", S.X)
                .Insert("Y", S.Y)
                .Insert("Map", S.Map)
                .Insert("Mesh", S.Mesh)
                .Insert("Flag", S.Flag);
                cmd.Execute();
        }
        public static void GetNpcs()
        {
            MySqlCommand cmd = new MySqlCommand(MySqlCommandType.SELECT);
            cmd.Select("npcs");
            MySqlReader r = new MySqlReader(cmd);
            while (r.Read())
            {
                Program.npcsInDatabase.Add(r.ReadUInt32("UID"));
            }
            Console.WriteLine("loaded " + Program.npcsInDatabase.Count + " npcs from database");
        }
        public static void AddSOB(Sob S)
        {
            MySqlCommand cmd = new MySqlCommand(MySqlCommandType.INSERT);
            cmd.Insert("Sobs")
                .Insert("UID", S.UID)
                .Insert("X", S.X)
                .Insert("Y", S.Y)
                .Insert("Map", S.Map)
                .Insert("Mesh", S.Type)
                .Insert("Flag", S.Flag)
                .Insert("MaxHp", S.Hp);
                cmd.Execute();
        }
Now in Client/Client.cs

above public class Client place

Code:
 public class LogNPC
    {
        public ushort Face, NPCID = 0;
        public List<String> Text = new List<String>();
        public Dictionary<byte, string> Links = new Dictionary<byte, string>();
    }
Inside the Client class (so lets just say right below sniffing)

Code:
public LogNPC RecordingNpc = null


Now in Packets/Handler.cs where Client packets are being handled
(public static void HandleClient(byte[] Data, Client Client)) place

Code:
 #region NPC REQUEST
                    case 2031:
                        {
                            if (Client.RecordingNpc != null)
                            {
                                Client.RecordingNpc = null;
                                return;
                            }
                            Client.RecordingNpc = new LogNPC();
                            Client.RecordingNpc.NPCID = (ushort)ReadUInt32(Data, 4);
                            break;
                        }
                    #endregion
obviously this goes in the main switch statement.


Now in the handle server side ( public static void HandleServer(byte[] Data, Client Client, bool Modify)) place

Code:
 #region SOB LOGGER
                        case 1109:
                            {
                                Sob S = new Sob();
                                S.UID = ReadUInt32(Data, 4);
                                S.Type = ReadUInt16(Data, 24);
                                S.Hp = ReadUInt32(Data, 12);
                                S.Flag = ReadUInt16(Data, 26);
                                S.X = ReadUInt16(Data, 20);
                                S.Y = ReadUInt16(Data, 22);
                                S.Map = Client.Map;
                                Database.AddSOB(S);
                                break;
                            }
                        #endregion
                        #region NPC LOGGER
                        case 2032:
                            if (Client.RecordingNpc != null)
                            {
                                Client.ToClientQueue.Enqueue(Data);
                                send = false;
                                switch (Data[11])
                                {
                                    case 1:
                                        Client.RecordingNpc.Text.Add(ReadString(Data, 14, Data[13]).Replace('~', ' '));
                                        break;
                                    case 2:
                                        Client.RecordingNpc.Links.Add(Data[10], ReadString(Data, 14, Data[13]).Replace('~', ' '));
                                        break;
                                    case 4://face
                                        Client.RecordingNpc.Face = ReadUInt16(Data, 8);
                                        break;
                                    case 100:
                                        Handler.DumpNpc(Client);
                                        Client.RecordingNpc.NPCID = 0;
                                        Client.RecordingNpc = null;
                                        break;
                                }
                            }
                            break;
                        #endregion
#region SpawnNpc
                        case 2030:
                            {
                                Npc N = new Npc();
                                N.UID = ReadUInt32(Data, 4);
                                N.ID = ReadUInt32(Data, 8);
                                N.X = ReadUInt16(Data, 12);
                                N.Y = ReadUInt16(Data, 14);
                                N.Mesh = ReadUInt16(Data, 16);
                                N.Flag = Data[18];
                                N.Map = Client.Map;
                                if (!Program.npcsInDatabase.Contains(N.UID))
                                { Program.npcsInDatabase.Add(N.UID); Console.WriteLine("Adding new NPC ID: " + N.UID); Database.AddNpc(N); }

                                Location L = new Location();
                                L.X = ReadUInt16(Data, 12);
                                L.Y = ReadUInt16(Data, 14);
                                L.Map = Client.Map;
                                if (!Program.NpcLocations.Contains(L))
                                    Program.NpcLocations.Add(L);
                                if (Client.Alone)
                                    send = false;
                                break;
                            }
                        #endregion

What I did was to dump the npc I made a new .cs file (doesn't matter where) and put this

Code:
 public partial class Handler
    {
        public static void DumpNpc(Client C)
        {
            try
            {
                if (C.RecordingNpc == null)
                    return;
                if (File.Exists(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"))
                    File.Delete(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc");
                StreamWriter SW = new StreamWriter(File.Create(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"));
                SW.WriteLine("def npc(Client, Option):");
                SW.WriteLine("    if(Option == 0):");
                foreach (String Text in C.RecordingNpc.Text)
                    SW.WriteLine("        Text(\"" + Text + "\")");
                foreach (KeyValuePair<byte, string> Option in C.RecordingNpc.Links)
                    SW.WriteLine("        Link(\"" + Option.Value + "\", " + Option.Key + ")");
                SW.WriteLine("        Face(" + C.RecordingNpc.Face + ")");
                SW.WriteLine("    return 0");
                SW.Close();
                SW.Flush();
                C.RecordingNpc = null;
            }
            catch { }
        }
    }
<<EDIT>>

You will also need the sob/npc classes (yes, I'm well aware I should have been using structs all through this but bite me)


Code:
public class Sob
    {
        public uint Type, UID, Hp;
        public ushort Flag, Map, X, Y;
    }
    public class Npc
    {
        public uint UID,ID;
        public byte Flag;
        public ushort Mesh, Map, X, Y;
    }
And you should be good to go.


Attached is the database I was logging the files to.

NOTE: you must place a folder called npcs in your debug folder for the scripts to write properly.


NOTEX2: Tq has changed the npc uids for most npcs. I'd suggest logging them all from scratch (make a new npc db + logging their scripts by talking to them) and use that.


NOTEX3: The way tq uses their npcs there is no simple way to log more than the first page of dialogue. This is ONLY to make the server look more complete and save you some typing. They will not 'do' anything nor will they have any dialogue past the first page.
Attached Files
File Type: rar alchemy.rar (716 Bytes, 179 views)
pro4never is offline  
Thanks
8 Users
Old 03/28/2011, 19:56   #2
 
elite*gold: 0
Join Date: Aug 2010
Posts: 93
Received Thanks: 18
Thanks alot for putting it up,
great release.
sitdownson is offline  
Old 03/28/2011, 19:59   #3
 
F i n c h i's Avatar
 
elite*gold: 0
Join Date: Nov 2009
Posts: 785
Received Thanks: 422
Thanks Chris,
Gonna try it :3
F i n c h i is offline  
Old 03/28/2011, 20:57   #4
 
{ Angelius }'s Avatar
 
elite*gold: 0
Join Date: Aug 2010
Posts: 992
Received Thanks: 1,110
Dang .

i was thinking . Hell its gonna take forever to code the npcs .
but not anymore tho !

thats gonna save alot of time :xD
{ Angelius } is offline  
Old 03/28/2011, 21:53   #5
 
elite*gold: 0
Join Date: Aug 2010
Posts: 93
Received Thanks: 18
Im having 1 problem, I made the class file
and pasted:

public partial class Handler
{
public static void DumpNpc(Client C)
{
try
{
if (C.RecordingNpc == null)
return;
if (File.Exists(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"))
File.Delete(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc");
StreamWriter SW = new StreamWriter(File.Create(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"));
SW.WriteLine("def npc(Client, Option):");
SW.WriteLine(" if(Option == 0):");
foreach (String Text in C.RecordingNpc.Text)
SW.WriteLine(" Text(\"" + Text + "\")");
foreach (KeyValuePair<byte, string> Option in C.RecordingNpc.Links)
SW.WriteLine(" Link(\"" + Option.Value + "\", " + Option.Key + ")");
SW.WriteLine(" Face(" + C.RecordingNpc.Face + ")");
SW.WriteLine(" return 0");
SW.Close();
SW.Flush();
C.RecordingNpc = null;
}
catch { }
}
}

into it, but somehow I keep getting this error:

Error 1 The type or namespace name 'Client' could not be found (are you missing a using directive or an assembly reference?) C:\Users\Marvin.Marvin-PC\Desktop\Alchemy proxy \AlchemyProxy\AlchemyProxy\AlchemyProxy.cs 3 32 AlchemyProxy

Probaly a ''easy'' fix but I cant seem to fix it.
sitdownson is offline  
Old 03/28/2011, 22:19   #6
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
sounds to me like the .cs you added isn't even part of the original solution :O...

Make sure you're adding the new cs file to the alchemyproxy project and not the overall solution or w/e.


IE:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace AlchemyProxy
{
    public partial class Handler
    {
        public static void DumpNpc(Client C)
        {
            try
            {
                if (C.RecordingNpc == null)
                    return;
                if (File.Exists(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"))
                    File.Delete(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc");
                StreamWriter SW = new StreamWriter(File.Create(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"));
                SW.WriteLine("def npc(Client, Option):");
                SW.WriteLine("    if(Option == 0):");
                foreach (String Text in C.RecordingNpc.Text)
                    SW.WriteLine("        Text(\"" + Text + "\")");
                foreach (KeyValuePair<byte, string> Option in C.RecordingNpc.Links)
                    SW.WriteLine("        Link(\"" + Option.Value + "\", " + Option.Key + ")");
                SW.WriteLine("        Face(" + C.RecordingNpc.Face + ")");
                SW.WriteLine("    return 0");
                SW.Close();
                SW.Flush();
                C.RecordingNpc = null;
                C.RecordingNpc.NPCID = 0;
            }
            catch { }
        }
    }
}
is the entire .cs file for me
pro4never is offline  
Thanks
1 User
Old 03/28/2011, 22:25   #7
 
elite*gold: 0
Join Date: Aug 2010
Posts: 93
Received Thanks: 18
Quote:
Originally Posted by pro4never View Post
sounds to me like the .cs you added isn't even part of the original solution :O...

Make sure you're adding the new cs file to the alchemyproxy project and not the overall solution or w/e.


IE:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace AlchemyProxy
{
    public partial class Handler
    {
        public static void DumpNpc(Client C)
        {
            try
            {
                if (C.RecordingNpc == null)
                    return;
                if (File.Exists(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"))
                    File.Delete(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc");
                StreamWriter SW = new StreamWriter(File.Create(Application.StartupPath + @"\npcs\" + C.RecordingNpc.NPCID + ".npc"));
                SW.WriteLine("def npc(Client, Option):");
                SW.WriteLine("    if(Option == 0):");
                foreach (String Text in C.RecordingNpc.Text)
                    SW.WriteLine("        Text(\"" + Text + "\")");
                foreach (KeyValuePair<byte, string> Option in C.RecordingNpc.Links)
                    SW.WriteLine("        Link(\"" + Option.Value + "\", " + Option.Key + ")");
                SW.WriteLine("        Face(" + C.RecordingNpc.Face + ")");
                SW.WriteLine("    return 0");
                SW.Close();
                SW.Flush();
                C.RecordingNpc = null;
                C.RecordingNpc.NPCID = 0;
            }
            catch { }
        }
    }
}
is the entire .cs file for me
Lol my bad i failed so bad,
noticed i deleted this for some reason:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace AlchemyProxy

>< thanks anyway!
sitdownson is offline  
Old 03/29/2011, 02:13   #8
 
elite*gold: 0
Join Date: Aug 2004
Posts: 26
Received Thanks: 4
Thank you works like charm, this makes life easier .
Yaksha is offline  
Old 03/29/2011, 05:40   #9
 
BioHazarxPaul's Avatar
 
elite*gold: 0
Join Date: Nov 2005
Posts: 548
Received Thanks: 93
Quote:
Originally Posted by { Angelius } View Post
Dang .

i was thinking . Hell its gonna take forever to code the npcs .
but not anymore tho !

thats gonna save alot of time :xD
Its great having all the npcs setup, now you get to do the fun put and write/fix 200+ npcs xD
BioHazarxPaul is offline  
Thanks
1 User
Old 03/29/2011, 06:04   #10
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Yah still lots of work getting them fully functional but it gives you a nice template to work with and saves a ton of typing.


IE: this is what we're using essentially for our new server npcs. Should have all the main npcs working before closed beta even really starts lol
pro4never is offline  
Old 03/29/2011, 07:29   #11
 
elite*gold: 80
Join Date: Sep 2007
Posts: 642
Received Thanks: 168
I would just like to put an emphasis on this.

Quote:
NOTEX3: The way tq uses their npcs there is no simple way to log more than the first page of dialogue. This is ONLY to make the server look more complete and save you some typing. They will not 'do' anything nor will they have any dialogue past the first page.
Santa is offline  
Old 03/29/2011, 10:30   #12
 
elite*gold: 0
Join Date: Dec 2010
Posts: 97
Received Thanks: 11
i haven't understood anything, what does code do?
Pro4Never2 is offline  
Old 03/29/2011, 13:18   #13
 
chickmagnet's Avatar
 
elite*gold: 0
Join Date: Jun 2009
Posts: 372
Received Thanks: 53
Quote:
Originally Posted by Pro4Never2 View Post
i haven't understood anything, what does code do?
read post above urs and really sink it in
chickmagnet is offline  
Old 03/29/2011, 17:53   #14
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Quote:
Originally Posted by Pro4Never2 View Post
i haven't understood anything, what does code do?
It makes it so that you can use my proxy to build an npc/sob database (where what npcs are ingame) based on the official tq servers and when you talk to them it will build the npc scripts for the npcs you talk to.

IE: it fills in most of the basic text for you making your npc scripting that much easier.


That's why the new hellmouth server has all the npc locations/text that real conquer does.


pro4never is offline  
Old 03/29/2011, 19:40   #15
 
elite*gold: 0
Join Date: Aug 2010
Posts: 93
Received Thanks: 18
Newbie question..
Im confused with the ports/IP in the program.cs
anyone mind explain/help me?..
sitdownson is offline  
Reply


Similar Threads Similar Threads
Automaton Scripts python
12/17/2010 - Flyff Private Server - 1 Replies
hi Leute hi ******** ich war schon lange nicht mehr on und nun habe ich wieder lust und zeit Fame zu spielen ich suche wieder scripts in python geschrieben für automaton 1.3 pls hab schon SuFu und gegooglet leider nichts gefunden weis auch nimmer wie die scripts heisen. PM me oder post
PYTHON SCRIPTS AUSFÜHREN
03/12/2010 - Metin2 - 2 Replies
kennt jmd in metin2 n py script, das ein anderes script ausführt, oder weiß jmd wie man das macht??
agBot Loop Scripts [ Let's Make alist with Mobs Scripts ]
07/09/2008 - SRO Hacks, Bots, Cheats & Exploits - 228 Replies
Hello Everyone, i saw that everyone is getting stuck to make agBot Loop Script. so i though we should make a topic a mobs scripts. and i will start. :) Now for me i prefer to use notepad to make my scripts. How to install : Just Copy the code and paste in <bot folder>\config\config1\script\default.lst If we got more scripts, i will just make a webpage, where you can select Town, HP and MP Bots you wanna buy then the monster you want to kill. then it auto generate the script for you....



All times are GMT +1. The time now is 11:49.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.