Jump to content
Returning Members: Password Reset Required ×

Canyon Suite: A Comet project (for 6192)


Recommended Posts

Posted

The first , thanks for shared !

I believe it's driven by a spirit of dedication

But when I cloned the code repository locally, I found that I wanted to compile the source code and run it. . . This requires me to have strong code reading skills

Moreover, the database is not complete, and project files often have missing configuration items.

For example, when I tried to run the Canyon.GM.Panel project, even the most basic database link string was not included in the configuration items. I needed to compare them one by one and improve them.

Then you have to modify the warehousing mapping, and the table name does not correspond. . . .

Maybe I need to spend a lot of time on this, and there is no guidance document. . .

But it's still cool. This is best one of the `Conquer Online` open source projects I've seen that has a clearer structure and is easier to manage later.

And the structure of the database is also very clear, basically consistent with the official library, which surprised me. Unfortunately, there is no data reference.

Of course, this is also thanks to "Fang"'s open source contribution to the infrastructure project Comet.

Hope this gets better and better. . . .

I'm actually really happy seeing this project. Not a lot of projects get forked and improved in the Conquer Online community while also remaining open-source and active. This is one of the only examples I've seen. It's really cool to see Dragon also getting used for the launcher. You can always contribute back to his project via pull requests if you want to see those things.

Fang is my old name, btw. I changed it to Spirited a long time ago, but it still gets referenced here and there.

This is the original project Canyon was forked from: https://gitlab.com/spirited/comet

Posted

The first , thanks for shared !

I believe it's driven by a spirit of dedication

But when I cloned the code repository locally, I found that I wanted to compile the source code and run it. . . This requires me to have strong code reading skills

Moreover, the database is not complete, and project files often have missing configuration items.

For example, when I tried to run the Canyon.GM.Panel project, even the most basic database link string was not included in the configuration items. I needed to compare them one by one and improve them.

Then you have to modify the warehousing mapping, and the table name does not correspond. . . .

Maybe I need to spend a lot of time on this, and there is no guidance document. . .

But it's still cool. This is best one of the `Conquer Online` open source projects I've seen that has a clearer structure and is easier to manage later.

And the structure of the database is also very clear, basically consistent with the official library, which surprised me. Unfortunately, there is no data reference.

Of course, this is also thanks to "Fang"'s open source contribution to the infrastructure project Comet.

Hope this gets better and better. . . .

I'm actually really happy seeing this project. Not a lot of projects get forked and improved in the Conquer Online community while also remaining open-source and active. This is one of the only examples I've seen. It's really cool to see Dragon also getting used for the launcher. You can always contribute back to his project via pull requests if you want to see those things.

Fang is my old name, btw. I changed it to Spirited a long time ago, but it still gets referenced here and there.

This is the original project Canyon was forked from: https://gitlab.com/spirited/comet

I also think so... but i thinks some body really hard for setup canyon to test the game without guide....

Firstly, people need to have a good understanding of the Comet project. Secondly, they need to have a good foundation in C #, and then you need to have the ability to independently debug and solve problems before you can log in to the game.

I think an excellent product should be easy to use for anyone with simple configuration, although I know it's not a product, I'm just making a constructive idea.

I will also try to create my own server based on Comet in the future..

Posted

I am reworking the game source code using same base and code but simplifying things. There is no tutorial on this source to avoid leechers to create scam servers with this.

This source still need work and has some incomplete features but I believe it's pretty stable and works perfectly with official stuff (LUA and DB), I provided a lot of stuff that even incomplete would be enough for scammers to create servers easily, so I will not provide a guide for this.

Even for me it takes some time to setup hosting environments, and I say this because I had to setup a US server after couple months of my BR one.

Don't get me wrong, but after the first complete setup you'll see how it's easy to work on Canyon.

Posted

So I think I figured it out, I didn't configure the api part of the accs, I'll try to remove it and add it via mysql.

Just define the preprocessor variable USE_MYSQL_DB

https://gitlab.com/world-conquer-online/canyon/canyon/-/blob/main/src/Canyon.Login/Sockets/Login/Packets/MsgAccount.cs?ref_type=heads#L21

Just add a try/catch block to avoid logins getting stuck if DB is not online

https://gitlab.com/world-conquer-online/canyon/canyon/-/blob/main/src/Canyon.Login/Repositories/AccountRepository.cs?ref_type=heads#L7

I had already defined it, and ended up in the Account Repository, now I'm going to create this part of the try.

The first , thanks for shared !

I believe it's driven by a spirit of dedication

But when I cloned the code repository locally, I found that I wanted to compile the source code and run it. . . This requires me to have strong code reading skills

Moreover, the database is not complete, and project files often have missing configuration items.

For example, when I tried to run the Canyon.GM.Panel project, even the most basic database link string was not included in the configuration items. I needed to compare them one by one and improve them.

Then you have to modify the warehousing mapping, and the table name does not correspond. . . .

Maybe I need to spend a lot of time on this, and there is no guidance document. . .

But it's still cool. This is best one of the `Conquer Online` open source projects I've seen that has a clearer structure and is easier to manage later.

And the structure of the database is also very clear, basically consistent with the official library, which surprised me. Unfortunately, there is no data reference.

Of course, this is also thanks to "Fang"'s open source contribution to the infrastructure project Comet.

Hope this gets better and better. . . .

The hardest part they've already done, the emulator is ''ready'', regarding the documentation, any line of code you put in a chat bot will tell you what it's for and what it does, the person just has to run after it. and find out :D

Posted
I mean, I'm personally in favor of making things more accessible rather than obfuscated. There's no stopping scammers in any private server community; Conquer Online isn't an exception to that. But making things more accessible also means an easier entry point for those who aren't as well versed in C#. On that note though, just due to the complexity of Conquer Online and the state of projects as a whole, there's really no getting around needing to know C# right now. Saying that's a requirement is sorta gonna get you a "well, duh" response from most people. Maybe that can change sometime in the future (like Comet was going to be dockerized with a dashboard / installation web project for setting it up easily), but that's just the state of things for now.
Posted

I mean, I'm personally in favor of making things more accessible rather than obfuscated. There's no stopping scammers in any private server community; Conquer Online isn't an exception to that. But making things more accessible also means an easier entry point for those who aren't as well versed in C#. On that note though, just due to the complexity of Conquer Online and the state of projects as a whole, there's really no getting around needing to know C# right now. Saying that's a requirement is sorta gonna get you a "well, duh" response from most people. Maybe that can change sometime in the future (like Comet was going to be dockerized with a dashboard / installation web project for setting it up easily), but that's just the state of things for now.

I'm working on a simplified version that I'm also trying to improve some stuff. It'll see sunlight soon and I'll replace the links in the main post.

It's not that I don't want to create a guide on how to setup stuff, but I tried to record a video and it took me more than 1 hour of explanations... then my wife just entered the room screaming because of a bug and I deleted it.

Posted

I am reworking the game source code using same base and code but simplifying things. There is no tutorial on this source to avoid leechers to create scam servers with this.

This source still need work and has some incomplete features but I believe it's pretty stable and works perfectly with official stuff (LUA and DB), I provided a lot of stuff that even incomplete would be enough for scammers to create servers easily, so I will not provide a guide for this.

Even for me it takes some time to setup hosting environments, and I say this because I had to setup a US server after couple months of my BR one.

Don't get me wrong, but after the first complete setup you'll see how it's easy to work on Canyon.

that's cool . I agree most about your idea to stop easy setup scam server ...

but ... i think scamer smart too .... just .... Maybe it's just setting obstacles for some beginners

That's why I have such doubts, but I fully appreciate your ideas and contributions, because it's really not easy

Posted

So I think I figured it out, I didn't configure the api part of the accs, I'll try to remove it and add it via mysql.

Just define the preprocessor variable USE_MYSQL_DB

https://gitlab.com/world-conquer-online/canyon/canyon/-/blob/main/src/Canyon.Login/Sockets/Login/Packets/MsgAccount.cs?ref_type=heads#L21

Just add a try/catch block to avoid logins getting stuck if DB is not online

https://gitlab.com/world-conquer-online/canyon/canyon/-/blob/main/src/Canyon.Login/Repositories/AccountRepository.cs?ref_type=heads#L7

I had already defined it, and ended up in the Account Repository, now I'm going to create this part of the try.

The first , thanks for shared !

I believe it's driven by a spirit of dedication

But when I cloned the code repository locally, I found that I wanted to compile the source code and run it. . . This requires me to have strong code reading skills

Moreover, the database is not complete, and project files often have missing configuration items.

For example, when I tried to run the Canyon.GM.Panel project, even the most basic database link string was not included in the configuration items. I needed to compare them one by one and improve them.

Then you have to modify the warehousing mapping, and the table name does not correspond. . . .

Maybe I need to spend a lot of time on this, and there is no guidance document. . .

But it's still cool. This is best one of the `Conquer Online` open source projects I've seen that has a clearer structure and is easier to manage later.

And the structure of the database is also very clear, basically consistent with the official library, which surprised me. Unfortunately, there is no data reference.

Of course, this is also thanks to "Fang"'s open source contribution to the infrastructure project Comet.

Hope this gets better and better. . . .

The hardest part they've already done, the emulator is ''ready'', regarding the documentation, any line of code you put in a chat bot will tell you what it's for and what it does, the person just has to run after it. and find out :D

YEA. I know that'.... THKS

Posted

I mean, I'm personally in favor of making things more accessible rather than obfuscated. There's no stopping scammers in any private server community; Conquer Online isn't an exception to that. But making things more accessible also means an easier entry point for those who aren't as well versed in C#. On that note though, just due to the complexity of Conquer Online and the state of projects as a whole, there's really no getting around needing to know C# right now. Saying that's a requirement is sorta gonna get you a "well, duh" response from most people. Maybe that can change sometime in the future (like Comet was going to be dockerized with a dashboard / installation web project for setting it up easily), but that's just the state of things for now.

HAHA ...

That's really right

“ There's no stopping scammers in any private server community” change " There's no stopping scammers in any where"

scammer study scam very time ... because, it's they work ...

Posted

I mean, I'm personally in favor of making things more accessible rather than obfuscated. There's no stopping scammers in any private server community; Conquer Online isn't an exception to that. But making things more accessible also means an easier entry point for those who aren't as well versed in C#. On that note though, just due to the complexity of Conquer Online and the state of projects as a whole, there's really no getting around needing to know C# right now. Saying that's a requirement is sorta gonna get you a "well, duh" response from most people. Maybe that can change sometime in the future (like Comet was going to be dockerized with a dashboard / installation web project for setting it up easily), but that's just the state of things for now.

I'm working on a simplified version that I'm also trying to improve some stuff. It'll see sunlight soon and I'll replace the links in the main post.

It's not that I don't want to create a guide on how to setup stuff, but I tried to record a video and it took me more than 1 hour of explanations... then my wife just entered the room screaming because of a bug and I deleted it.

take care .... keep family emotion heath is more importants.... BRO

Posted
I don't know what I did that now, it no longer connected to the realm :c it reported the error: REALM_DOES_NOT_EXIST, and it continues as it was in the database, and before it connected to the realm.
  • 2 weeks later...
Posted

I tried using the Dragon launcher in the OP, but running the launcher seems to start the client but as soon as the login screen should open the client closes, any idea on why that would be?

Edit: if i do not inject the connect module than it starts just fine.

Posted

I tried using the Dragon launcher in the OP, but running the launcher seems to start the client but as soon as the login screen should open the client closes, any idea on why that would be?

Edit: if i do not inject the connect module than it starts just fine.

Probably your Conquer.exe is wrong and is crashing because the injected addresses dont match.

I think that the address in the repository are for the 6135 client, I am making a commit to update with 6192 addresses.

Also they're not complete, they will bug transformations and a few meshes and need to be sorted for a solution, but you'll be able to login.

https://gitlab.com/world-conquer-online/canyon/dragon/-/commit/f9122b199791d387f4cc175d507795a09873e1b0

Posted

I tried using the Dragon launcher in the OP, but running the launcher seems to start the client but as soon as the login screen should open the client closes, any idea on why that would be?

Edit: if i do not inject the connect module than it starts just fine.

you can try use easy loader firsth

...

give you mine .... try it

ConquerLoader&EXE.rar

  • 2 weeks later...
Posted

Hello, first of all thank you for the effort it is an interesting base and full of challenges, I managed to get the server up even though the mobs did not load, could you help me with this LUA "LinkMonsterMain" to take it as an example, perhaps it is because I am missing this LUA.

Sorry my bad English

Posted

Use this snip to set the monster drop.

tMonster[3131] = tMonster[3131] or {}
tMonster[3131]["tFunction"] = tMonster[3131]["tFunction"] or {}
table.insert(tMonster[3131]["tFunction"],Canyon_TitanGanodermaDrop)

Examples:

------------------------------------------------------------------------------------
--Name:		[Canyon]TitanGanoderma
--Purpose:	Defines drops for those monsters.
--Creator: 	Felipe Vieira Vendramini
--Created:	2023/07/27
------------------------------------------------------------------------------------

local tTitanGanodermaPotions = {}
tTitanGanodermaPotions["2xExpPotion30Min"] = 728775
tTitanGanodermaPotions["3xExpPotion30Min"] = 728776
tTitanGanodermaPotions["5xExpPotion30Min"] = 728777
tTitanGanodermaPotions["5xExpPotion1Hour"] = 728810

tTitanGanodermaPotions["2xExpPotion1Hour"] = 723017
tTitanGanodermaPotions["3xExpPotion2Hour"] = 720393
tTitanGanodermaPotions["5xExpPotion2Hour"] = 720394


function Canyon_TitanGanodermaDrop()

   local nRate = math.random(1, 100)
   local nUserId = Get_UserId()

   if nRate <= 20 then
       nRate = math.random(1, 100)
       if nRate <= 15 then -- 15% 5x
           Monster_SysDropItem(tTitanGanodermaPotions["5xExpPotion2Hour"], nUserId)
       elseif nRate <= 40 then -- 25% 3x
           Monster_SysDropItem(tTitanGanodermaPotions["3xExpPotion2Hour"], nUserId)
       else
           Monster_SysDropItem(tTitanGanodermaPotions["2xExpPotion1Hour"], nUserId)
       end
   else
       nRate = math.random(1, 100)
       -- rate for exp potions
       if nRate <= 7 then -- 7% 5x exp potion 1 hour
           Monster_SysDropItem(tTitanGanodermaPotions["5xExpPotion1Hour"], nUserId)
       elseif nRate <= 25 then -- 18 % 5x exp potion 30 min
           Monster_SysDropItem(tTitanGanodermaPotions["5xExpPotion30Min"], nUserId)
       elseif nRate <= 50 then -- 25% 3x exp potion 30 min
           Monster_SysDropItem(tTitanGanodermaPotions["3xExpPotion30Min"], nUserId)
       else -- 2x exp potion 30 min
           Monster_SysDropItem(tTitanGanodermaPotions["2xExpPotion30Min"], nUserId)
       end
   end

   nRate = math.random(1, 100)
   if nRate <= 5 then
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
   elseif nRate <= 20 then
       Monster_SysDropItem(1088000, nUserId) -- drop dragon ball
   end

end

------------------------------------------------------------------------------------
-- Monster drops
------------------------------------------------------------------------------------

tMonster[3130] = tMonster[3130] or {}
tMonster[3130]["tFunction"] = tMonster[3130]["tFunction"] or {}
table.insert(tMonster[3130]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3131] = tMonster[3131] or {}
tMonster[3131]["tFunction"] = tMonster[3131]["tFunction"] or {}
table.insert(tMonster[3131]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3132] = tMonster[3132] or {}
tMonster[3132]["tFunction"] = tMonster[3132]["tFunction"] or {}
table.insert(tMonster[3132]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3133] = tMonster[3133] or {}
tMonster[3133]["tFunction"] = tMonster[3133]["tFunction"] or {}
table.insert(tMonster[3133]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3134] = tMonster[3134] or {}
tMonster[3134]["tFunction"] = tMonster[3134]["tFunction"] or {}
table.insert(tMonster[3134]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3135] = tMonster[3135] or {}
tMonster[3135]["tFunction"] = tMonster[3135]["tFunction"] or {}
table.insert(tMonster[3135]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3136] = tMonster[3136] or {}
tMonster[3136]["tFunction"] = tMonster[3136]["tFunction"] or {}
table.insert(tMonster[3136]["tFunction"],Canyon_TitanGanodermaDrop)

tMonster[3137] = tMonster[3137] or {}
tMonster[3137]["tFunction"] = tMonster[3137]["tFunction"] or {}
table.insert(tMonster[3137]["tFunction"],Canyon_TitanGanodermaDrop)

------------------------------------------------------------------------------------

I did this also for CPs/DB drop

------------------------------------------------------------------------------------
--Name:		[Canyon]MonsterDrop
--Purpose:	Defines an interface for all common monsters drop.
--Creator: 	Felipe Vieira Vendramini
--Created:	2023/07/17
------------------------------------------------------------------------------------

------------------------------------------------------------------------------------
-- Parameters
-- ItemType: the item type to be dropped
-- Money: amount of money to be dropped
-- ConquerPoints: amount of Conquer Points to be dropped
-- ConquerPointsMono: amount of CPs(B) to be dropped
-- MinRate: n in MaxRate
-- MaxRate: MinRate in n
-- Rate: n in 10000
-- AutoHunt: [boolean] if set means that it will be dropped only on auto hunt or off
-- Child: [Object array]
-- OpenDate: [yyyy-MM-dd HH:mm] when drop starts
-- CloseDate: [yyyy-MM-dd HH:mm] when drop ends
-- Message: Valid for parent and child, no args
-- ActionLog: Always require two integer args, monsterid and mapid
------------------------------------------------------------------------------------
-- When Child is set Rate will define the coeficient for the drops inside
-- Rate inside of a child is the amount necessary for that element
-- Example: if main object has 100 MaxRate all Childs must set a Rate, or they wont
-- be hit.
-- generatedRandom = rand(Parent[MaxRate])
-- if child[Rate] < generatedRandom then drop
-- Max depth = 1
------------------------------------------------------------------------------------

local tCanyonValidMonsterDrops = {}
   -- [1088000] DragonBall
   tCanyonValidMonsterDrops[1] = {}
   tCanyonValidMonsterDrops[1]["ItemType"] = 1088000
   tCanyonValidMonsterDrops[1]["MinRate"] = 2350
   tCanyonValidMonsterDrops[1]["MaxRate"] = 10200000
   tCanyonValidMonsterDrops[1]["Message"] = "You have found a Dragon Ball."
   tCanyonValidMonsterDrops[1]["ActionLog"] = "%d,%d,1,1088000,2350,10200000"
   tCanyonValidMonsterDrops[1]["AutoHunt"] = true

   -- Conquer Points
   tCanyonValidMonsterDrops[2] = {}
   tCanyonValidMonsterDrops[2]["ConquerPoints"] = 215
   tCanyonValidMonsterDrops[2]["MinRate"] = 2350
   tCanyonValidMonsterDrops[2]["MaxRate"] = 10200000
   tCanyonValidMonsterDrops[2]["Message"] = "You have found 215 CPs."
   tCanyonValidMonsterDrops[2]["ActionLog"] = "%d,%d,2,215,2350,10200000"
   tCanyonValidMonsterDrops[2]["Effect"] = "angelwing"
tCanyonValidMonsterDrops[2]["AutoHunt"] = false

   -- [700001-700061] Common Gems
   tCanyonValidMonsterDrops[3] = {}
   tCanyonValidMonsterDrops[3]["MinRate"] = 130
   tCanyonValidMonsterDrops[3]["MaxRate"] = 350000
   tCanyonValidMonsterDrops[3]["Rate"] = 100
   tCanyonValidMonsterDrops[3]["Child"] = {}
   tCanyonValidMonsterDrops[3]["Child"][1] = {}
   tCanyonValidMonsterDrops[3]["Child"][1]["Rate"] = 10
   tCanyonValidMonsterDrops[3]["Child"][1]["ItemType"] = 700001
   tCanyonValidMonsterDrops[3]["Child"][2] = {}
   tCanyonValidMonsterDrops[3]["Child"][2]["Rate"] = 20
   tCanyonValidMonsterDrops[3]["Child"][2]["ItemType"] = 700011
   tCanyonValidMonsterDrops[3]["Child"][3] = {}
   tCanyonValidMonsterDrops[3]["Child"][3]["Rate"] = 30
   tCanyonValidMonsterDrops[3]["Child"][3]["ItemType"] = 700021
   tCanyonValidMonsterDrops[3]["Child"][4] = {}
   tCanyonValidMonsterDrops[3]["Child"][4]["Rate"] = 40
   tCanyonValidMonsterDrops[3]["Child"][4]["ItemType"] = 700031
   tCanyonValidMonsterDrops[3]["Child"][5] = {}
   tCanyonValidMonsterDrops[3]["Child"][5]["Rate"] = 50
   tCanyonValidMonsterDrops[3]["Child"][5]["ItemType"] = 700041
   tCanyonValidMonsterDrops[3]["Child"][6] = {}
   tCanyonValidMonsterDrops[3]["Child"][6]["Rate"] = 60
   tCanyonValidMonsterDrops[3]["Child"][6]["ItemType"] = 700051
   tCanyonValidMonsterDrops[3]["Child"][7] = {}
   tCanyonValidMonsterDrops[3]["Child"][7]["Rate"] = 70
   tCanyonValidMonsterDrops[3]["Child"][7]["ItemType"] = 700061
   tCanyonValidMonsterDrops[3]["Child"][8] = {}
   tCanyonValidMonsterDrops[3]["Child"][8]["Rate"] = 80
   tCanyonValidMonsterDrops[3]["Child"][8]["ItemType"] = 700071
   tCanyonValidMonsterDrops[3]["Child"][9] = {}
   tCanyonValidMonsterDrops[3]["Child"][9]["Rate"] = 90
   tCanyonValidMonsterDrops[3]["Child"][9]["ItemType"] = 700101
   tCanyonValidMonsterDrops[3]["Child"][10] = {}
   tCanyonValidMonsterDrops[3]["Child"][10]["Rate"] = 100
   tCanyonValidMonsterDrops[3]["Child"][10]["ItemType"] = 700121

   -- [1088001] Meteor
   tCanyonValidMonsterDrops[4] = {}
   tCanyonValidMonsterDrops[4]["ItemType"] = 1088001
   tCanyonValidMonsterDrops[4]["MinRate"] = 500
   tCanyonValidMonsterDrops[4]["MaxRate"] = 2700000
   tCanyonValidMonsterDrops[4]["ActionLog"] = "%d,%d,4,1088001,500,2700000"

   -- Conquer Points Bound
   tCanyonValidMonsterDrops[5] = {}
   tCanyonValidMonsterDrops[5]["MinRate"] = 43
   tCanyonValidMonsterDrops[5]["MaxRate"] = 15450
   tCanyonValidMonsterDrops[5]["Rate"] = 100
   tCanyonValidMonsterDrops[5]["Child"] = {}
   tCanyonValidMonsterDrops[5]["Child"][1] = {}
   tCanyonValidMonsterDrops[5]["Child"][1]["Rate"] = 25
   tCanyonValidMonsterDrops[5]["Child"][1]["ConquerPointsMono"] = 1
   tCanyonValidMonsterDrops[5]["Child"][1]["Message"] = "You`ve found 1 CP(B)."
   tCanyonValidMonsterDrops[5]["Child"][1]["ActionLog"] = "%d,%d,5,1,1,43,15450,25"
   tCanyonValidMonsterDrops[5]["Child"][2] = {}
   tCanyonValidMonsterDrops[5]["Child"][2]["Rate"] = 50
   tCanyonValidMonsterDrops[5]["Child"][2]["ConquerPointsMono"] = 3
   tCanyonValidMonsterDrops[5]["Child"][2]["Message"] = "You`ve found 3 CPs(B)."
   tCanyonValidMonsterDrops[5]["Child"][2]["ActionLog"] = "%d,%d,5,2,3,43,15450,50"
   tCanyonValidMonsterDrops[5]["Child"][3] = {}
   tCanyonValidMonsterDrops[5]["Child"][3]["Rate"] = 75
   tCanyonValidMonsterDrops[5]["Child"][3]["ConquerPointsMono"] = 5
   tCanyonValidMonsterDrops[5]["Child"][3]["Message"] = "You`ve found 5 CPs(B)."
   tCanyonValidMonsterDrops[5]["Child"][3]["ActionLog"] = "%d,%d,5,3,5,43,15450,75"
   tCanyonValidMonsterDrops[5]["Child"][4] = {}
   tCanyonValidMonsterDrops[5]["Child"][4]["Rate"] = 100
   tCanyonValidMonsterDrops[5]["Child"][4]["ConquerPointsMono"] = 7
   tCanyonValidMonsterDrops[5]["Child"][4]["Message"] = "You`ve found 7 CPs(B)."
   tCanyonValidMonsterDrops[5]["Child"][4]["ActionLog"] = "%d,%d,5,4,7,43,15450,100"

   -- FireOfHell
   tCanyonValidMonsterDrops[6] = {}
   tCanyonValidMonsterDrops[6]["ItemType"] = 1060101
   tCanyonValidMonsterDrops[6]["MinRate"] = 43
   tCanyonValidMonsterDrops[6]["MaxRate"] = 750000
   tCanyonValidMonsterDrops[6]["ActionLog"] = "%d,%d,6,1060101,43,750000"

   -- Bomb
   tCanyonValidMonsterDrops[7] = {}
   tCanyonValidMonsterDrops[7]["ItemType"] = 1060100
   tCanyonValidMonsterDrops[7]["MinRate"] = 43
   tCanyonValidMonsterDrops[7]["MaxRate"] = 450000
   tCanyonValidMonsterDrops[6]["ActionLog"] = "%d,%d,7,1060100,43,450000"

local tCanyonValidMonsterTypeIds = {
   1, --	    Pheasant
   2, --	    Turtledove
   3, --	    Robin
   4, --	    Apparition
   5, --	    Poltergeist
   6, --	    WingedSnake
   7, --	    Bandit
   8, --	    Ratling
   9, --	    FireSpirit
   10, --	    Macaque
   11, --	    GiantApe
   12, --	    ThunderApe
   13, --	    Snakeman
   14, --	    SandMonster
   15, --	    HillMonster
   16, --	    RockMonster
   17, --	    BladeGhost
   18, --	    Birdman
   19, --	    HawKing
   20, --	    TombBat
   55, --	    BanditL97
   56, --	    BloodyBat
   57, --	    BullMonster
   58, --	    RedDevilL117
   59, --	    RockMonsterL15
   64, --	    HeavyGhostL23
   65, --	    WingedSnakeL28
   66, --	    BanditL33
   67, --	    FireRatL38
   68, --	    FireSpiritL43
   69, --	    MacaqueL48
   70, --	    GiantApeL53
   71, --	    ThunderApeL58
   72, --	    SnakemanL63
   73, --	    SandMonsterL68
   74, --	    HillMonsterL73
   75, --	    RockMonsterL78
   76, --	    BladeGhostL83
   77, --	    BirdmanL88
   78, --	    HawkL93
   79, --	    BanditL98
   80, --	    TombBatL103
   81, --	    BloodyBatL108
   82, --	    BullMonsterL113
   83, --	    RedDevilL118
   84, --	    Banditti
   120, --     ElfApe
   121, --     SlowApe
   122, --     SnakeMonster
   1400, --	HugeSnake
   1401, --	BanditLeader
   1402, --	HugeSpirit
   1403, --	CateranSoldier
   1404, --	SeniorCateran
   1405, --	CateranLeader
   1406, --	ChiefCateran
   1407, --	HugeApe
   1408, --	SeniorApe
   1409, --	AlienApe
   1410, --	SeniorSnakeman
   1411, --	Serpent
   1412, --	SeniorSerpent
   1413, --	AlienSerpent
   1414, --	Basilisk
   2410, --	SerpentEnvoy
   2411, --	IcySerpent
   2412, --	SerpentLord
   2413, --	SerpentKing
   2414, --	FrostSerpent
   2415, --	BladeDevilEnvoy
   2416, --	IcyBladeDevil
   2417, --	BladeDevilLord
   2418, --	BladeDevilKing
   2419, --	FrostBladeDevil
   2460, --	DarkLady
   2461, --	DarkElf
   2465, --	NightmareLady
   2466, --	GrottoLady
   2473, --	SnakeChief
   2474, --	SnakeHubbub
   2478, --	HeadlessGeneral
   2479, --	HeadlessSoldier
}

local tCanyonMonsterDropLogFilename = "lua_monster_drop"

function Canyon_MonsterDropRegister()
   for index, value in pairs(tCanyonValidMonsterTypeIds) do
       tMonster[value] = tMonster[value] or {}
       tMonster[value]["tFunction"] = tMonster[value]["tFunction"] or {}
       table.insert(tMonster[value]["tFunction"],Canyon_MonsterDrop)
   end
end

function Canyon_MonsterDropContainsMonster(nMonsterType)
   for index, value in pairs(tCanyonValidMonsterTypeIds) do
       if value == nMonsterType then
           return true
       end
   end
   return false
end

function Canyon_MonsterDrop()
   local nMonsterId = Get_MonsterType()
   local nUserId = Get_UserId()

   if type(nMonsterId) ~= "number" or nMonsterId <= 0 then
       Sys_SaveAbnormalLog("Canyon_MonsterDrop called by a non monster")
       return
   end

   if not Canyon_MonsterDropContainsMonster(nMonsterId) then
       return
   end

   for i, v in pairs(tCanyonValidMonsterDrops) do
       if Sys_Random(v["MinRate"], v["MaxRate"]) then
           if v["Child"] ~= nil then
               if v["Rate"] == nil or type(v["Rate"]) ~= "number" or v["Rate"] < 2 then
                   Sys_SaveAbnormalLog(string.format("Canyon_MonsterDrop invalid rate [%s] for child [%d]!", v["Rate"], i))
               else
                   local nLocalRate = math.random(1, v["Rate"])
                   for localIndex, localValue in pairs(v["Child"]) do
                       if nLocalRate < localValue["Rate"] then
                           if Canyon_MonsterDropExecute(localValue, nUserId) then
                               if v["Effect"] ~= nil then
                                   User_EffectAdd("self", v["Effect"])
                               end
                               if localValue["Effect"] ~= nil then
                                   User_EffectAdd("self", localValue["Effect"])
                               end
                               if localValue["Message"] ~= nil then
                                   User_TalkChannel2005(localValue["Message"])
                               end
                               if localValue["ActionLog"] ~= nil then
                                   Sys_SaveActionParamLog(tCanyonMonsterDropLogFilename, string.format(localValue["ActionLog"], Get_MonsterType(0), Get_MonsterMapID(0)))
                               end
                           end
                           return
                       end -- leave Canyon_MonsterDropExecute(localValue)
                   end -- leave local for
               end -- end child drop rate
           else
               if Canyon_MonsterDropExecute(v, nUserId) == true then
                   if v["Effect"] ~= nil then
                       User_EffectAdd("self", v["Effect"])
                   end
                   if v["Message"] ~= nil then
                       User_TalkChannel2005(v["Message"])
                   end
                   if v["ActionLog"] ~= nil then
                       Sys_SaveActionParamLog(tCanyonMonsterDropLogFilename, string.format(v["ActionLog"], Get_MonsterType(0), Get_MonsterMapID(0)))
                   end
                   return
               end -- leave Canyon_MonsterDropExecute
           end -- leave child if
       end -- leave sys random if
   end -- leave for
end -- end function

function Canyon_MonsterDropExecute(v, nUserId)
   if v["AutoHunt"] ~= nil and type(v["AutoHunt"]) == "boolean" then
       local isAutoHunting = IsAutoHangUp(0)
       if v["AutoHunt"] == false and isAutoHunting == true then
           return false
       end
   end

   if v["Money"] ~= nil and type(v["Money"] == "number" and v["Money"] > 0) then
       User_AddMoney(v["Money"])
       return true
   end

   if v["ConquerPoints"] ~= nil and type(v["ConquerPoints"] == "number" and v["ConquerPoints"] > 0) then
       User_AddEMoney(v["ConquerPoints"])
       return true
   end

   if v["ConquerPointsMono"] ~= nil and type(v["ConquerPointsMono"] == "number" and v["ConquerPointsMono"] > 0) then
       User_AddEMoneyMono(v["ConquerPointsMono"])
       return true
   end

   if v["ItemType"] ~= nil and type(v["ItemType"]) == "number" and v["ItemType"] > 0 then
       if v["ItemTypeMode"] == nil or v["ItemTypeMode"] == "drop" then
           Monster_SysDropItem(v["ItemType"], nUserId)
           return true
       else
           if nUserId ~= nil and type(nUserId) == "number" and nUserId > 0 then
               Item_AddNewItem(v["ItemType"], "", nUserId)
               return true
           end
       end
   end
   return false
end

tServerStart["tFunction"] = tServerStart["tFunction"] or {}
table.insert(tServerStart["tFunction"],Canyon_MonsterDropRegister)

Posted

Thank you, it has helped me a lot, it took me a while to understand the LUA system but I have managed to modify the system to create dialogues and actions of the npc from lua functions

Captura-de-pantalla-2024-04-08-164306.png

Captura-de-pantalla-2024-04-08-164513.png

I still use cq_action for the main call so I can call actions, params(args) and lua functions

110000 0 0 20002 0 NpcExcecuteTest

110001 0 0 20002 0 NpcExcecuteTest_Option1

110002 0 0 20002 0 NpcExcecuteTest_Option2

110003 0 0 20002 0 NpcExcecuteTest_DarDinero

110004 0 0 20002 0 NpcExcecuteTest_DarCPS

Posted (edited)

Thank you, it has helped me a lot, it took me a while to understand the LUA system but I have managed to modify the system to create dialogues and actions of the npc from lua functions

You don't need to use actions, you can do everything from the LUA Script.

If you have the leaked LUAs, there are some functions..

-- 101 Sys_DialogText(sText,nline)
-- 102 Sys_DialogOption(sOptionText,strFunc,nAlign)
-- 103 Sys_DialogOptEdit(sText,nLen,sFunc,nPassword)
-- 104 Sys_DialogFace(nNpcID)
-- 105 Sys_MsgBox(sText,sFunc,sFailFunc)
-- 120 Sys_DialogEnd(strFunc)
-- 123 Sys_ChkFullTime(sParam)
-- 124 Sys_PostCmd(nData)
-- 125 Sys_NormalBroadcast(sContent)
-- 125 Sys_ActionBroadcast(sContent)
-- 125 Sys_TeamBroadcast(sContent)
-- 125 Sys_SystemBroadcast(sContent)
-- 125 Sys_TalkBroadcast(sContent)
-- 125 Sys_GmBroadcast(sContent)
-- 129 Sys_InviteFilter(nInivteId,sParam)
-- 129 Sys_DelInvite(nInivteId)
-- 130 Sys_InviteTrans(nMapId,tTransPosx,nStrSendInviteId,nStrTransOKId,nInviteId,nCloseSecs)
-- 131 Sys_GotoSomeWhere(nPosX,nPosY,nMapId,nNpcId,nUserId)

-- 对应actiontype = 113
-- 清除对话框Task计数
-- 参数1:idUser表示玩家ID, 填0表示自己。如果失败返回false,成功返回true.
-- bool MenuTaskClear(UINT idUser);
-- Sys_DialogTaskClear()

-- #判断是否打开二级密码
-- 对应ACTION:1053
-- LUA接口:IsOpenSecondPWD
-- 参数1:玩家id
-- 返回值:true表示打开二级密码 false表示没有打开二级密码
-- Sys_IsOpenSecondPWD(nUserId)

I'm adding some LUA files here instead of writing to the post.

Canyon-lua.zip

Edited by Konichu
Posted

First, thank you for your good work, but I have some suggestions, with artificial intelligence, why is there no cross server system, transfer servers, and why is there no build, complete with script

Artificial intelligence isn't a replacement for real intelligence and talent. It can only do so much using guesses at what problems are solved by Stack Overflow. It's no more helpful than Googling, and may be worse since it only gives you a single opinion without source references. I strongly advise against the use of AI in Conquer Online server development. It has no idea what Conquer's internal data structures or messages are, nor the contents and meaning of your own source / this project. A "prompt engineer" is not an actual engineer.

With that said, a reminder to the community when working with these LUA scripts: they are from a binary leak from TQ, and distributing them is not allowed here. You're welcome to talk about them here, just don't distribute them. Thanks!

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...