|
You last visited: Today at 06:46
Advertisement
Multiple entities kills bug
Discussion on Multiple entities kills bug within the CO2 Private Server forum part of the Conquer Online 2 category.
10/28/2013, 09:59
|
#1
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
Multiple entities kills bug
I have a problem with scatter, fire ring and all the others skills that kills multiple monsters/players. -> It doesn't do the effect nor the moves of the skills. Like, with scatter I don't see arrows, I don't see the moves of the character but it happens only sometimes. I've checked the screen.cs with a friend (It's not the scatter code since every skills that kills multiple mobs do that) and we didn't find anything wrong with it. Here's a video to show the problem if you don't understand what I mean:
If someone have any idea, I'd be grateful because i'm trying to find the base of this bug for a week lol.
P.S: It's not the number of monsters, I checked and even if there's 3 monsters it won't do the action.
Thanks, Nova.
|
|
|
10/28/2013, 11:02
|
#2
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 950
|
Have you tried debugging?
It could be that something is blocking the attack-handler from sending the skill animation, but the death of the mobs has been handled before that.
Perhaps check for exceptions and make sure it's not some empty catch block that does it.
|
|
|
10/28/2013, 11:24
|
#3
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
I already tried debugging and I don't think it's a block of the attack-handler since it only kills x of x monsters in the area but I'll check for it & exceptions. While I'm checking, If someone have other ideas of where this problem comes, Feel free to post
|
|
|
10/30/2013, 00:30
|
#4
|
elite*gold: 0
Join Date: Aug 2010
Posts: 992
Received Thanks: 1,110
|
I am just guessing here but.. In your 1105 packet aka the magic attack packet make sure that data 4 or data 8 if you are on the latest patch is set to the attacker UID and not 0 or any random number/monster UID.
|
|
|
10/30/2013, 02:22
|
#5
|
elite*gold: 0
Join Date: Feb 2006
Posts: 726
Received Thanks: 271
|
Quote:
Originally Posted by { Angelius }
I am just guessing here but.. In your 1105 packet aka the magic attack packet make sure that data 4 or data 8 if you are on the latest patch is set to the attacker UID and not 0 or any random number/monster UID.
|
Wouldn't that be bug be present all the time and completely prevent the packet being sent?
I guess it depends how they have it structured.
Definitely theres something happening that is preventing that packet from sending.
Maybe theres an attack time check?
Without seeing the attack code its hard to debug
|
|
|
10/30/2013, 03:41
|
#6
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
I checked and I didn't see anything wrong that could make that bug. But I'm a beginner in C# so here's the codes that could be concerned with this. Thanks to the persons that are trying to help me out, I appreciate it.
Attack.cs
Code:
using System;
namespace Conquer_Online_Server.Network.GamePackets
{
public class Attack : Interfaces.IPacket
{
public const uint Melee = 2,
MarriageRequest = 8,
MarriageAccept = 9,
Kill = 14,
Magic = 24,
Reflect = 26,
Dash = 27,
Ranged = 28,
MonkMelee = 34,
MerchantAccept = 40,
MerchantRefuse = 41,
MerchantProgress = 42,
Scapegoat = 43,
CounterKillSwitch = 44,
FatalStrike = 45,
ShowUseSpell = 52,
InteractionRequest = 46,
InteractionAccept = 47,
InteractionRefuse = 48,
InteractionEffect = 49,
InteractionStopEffect = 50;
byte[] Buffer;
public Attack(bool Create)
{
if (Create)
{
Buffer = new byte[8 + 32];
Writer.WriteUInt16(32, 0, Buffer);
Writer.WriteUInt16(1022, 2, Buffer);
}
}
public uint Attacker
{
get { return BitConverter.ToUInt32(Buffer, 8); }
set { Writer.WriteUInt32(value, 8, Buffer); }
}
public uint Attacked
{
get { return BitConverter.ToUInt32(Buffer, 12); }
set { Writer.WriteUInt32(value, 12, Buffer); }
}
public ushort X
{
get { return BitConverter.ToUInt16(Buffer, 16); }
set { Writer.WriteUInt16(value, 16, Buffer); }
}
public ushort Y
{
get { return BitConverter.ToUInt16(Buffer, 18); }
set { Writer.WriteUInt16(value, 18, Buffer); }
}
public uint AttackType
{
get { return BitConverter.ToUInt32(Buffer, 20); }
set { Writer.WriteUInt32(value, 20, Buffer); }
}
public uint Damage
{
get { return BitConverter.ToUInt32(Buffer, 24); }
set { Writer.WriteUInt32(value, 24, Buffer); }
}
public ushort KOCount
{
get { return BitConverter.ToUInt16(Buffer, 26); }
set { Writer.WriteUInt16(value, 26, Buffer); }
}
public uint ResponseDamage
{
get { return BitConverter.ToUInt32(Buffer, 28); }
set { Writer.WriteUInt32(value, 28, Buffer); }
}
public AttackEffects1 Effect1
{
get { return (AttackEffects1)Buffer[32]; }
set { Buffer[32] = (Byte)value; }
}
public AttackEffects2 Effect2
{
get { return (AttackEffects2)Buffer[33]; }
set { Buffer[33] = (Byte)value; }
}
[Flags]
public enum AttackEffects1 : byte
{
None = 0x0,
Block = 0x1,
Penetration = 0x2,
CriticalStrike = 0x4,
MetalResist = 0x10,
WoodResist = 0x20,
WaterResist = 0x40,
FireResist = 0x80,
}
[Flags]
public enum AttackEffects2 : byte
{
None = 0x0,
EarthResist = 0x1,
StudyPoints = 0x2,
}
public bool Decoded = false;
public void Deserialize(byte[] buffer)
{
this.Buffer = buffer;
}
public byte[] ToArray()
{
return Buffer;
}
public void Send(Client.GameState client)
{
client.Send(Buffer);
}
}
}
Ranged region in Handle.cs
Code:
#region Ranged
else if (attack.AttackType == Attack.Ranged)
{
if (attacker.Owner.Screen.TryGetValue(attack.Attacked, out attacked))
{
CheckForExtraWeaponPowers(attacker.Owner, attacked);
if (attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon) == null)
return;
if (!CanAttack(attacker, attacked, null, attack.AttackType == Attack.Melee))
return;
if (!attacker.Owner.Equipment.Free((byte)ConquerItem.LeftWeapon))
{
Interfaces.IConquerItem arrow = attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon);
arrow.Durability -= 1;
ItemUsage usage = new ItemUsage(true) { UID = arrow.UID, dwParam = arrow.Durability, ID = ItemUsage.UpdateDurability };
usage.Send(attacker.Owner);
if (arrow.Durability <= 0 || arrow.Durability > 5000)
{
Network.PacketHandler.ReloadArrows(attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon), attacker.Owner);
}
}
if (ServerBase.Kernel.GetDistance(attacker.X, attacker.Y, attacked.X, attacked.Y) <= ServerBase.Constants.pScreenDistance)
{
uint damage = Game.Attacking.Calculate.Ranged(attacker, attacked);
attack.Damage = damage;
if (attacker.EntityFlag == EntityFlag.Player && attacked.EntityFlag != EntityFlag.Player)
if (damage > attacked.Hitpoints)
{
attacker.Owner.IncreaseProficiencyExperience(Math.Min(damage, attacked.Hitpoints), 500);
}
else
{
attacker.Owner.IncreaseProficiencyExperience(damage, 500);
}
ReceiveAttack(attacker, attacked, attack, damage, null);
}
}
else if (attacker.Owner.Screen.TryGetSob(attack.Attacked, out attackedsob))
{
if (CanAttack(attacker, attackedsob, null))
{
if (attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon) == null)
return;
if (attacker.MapID != 1039)
{
if (!attacker.Owner.Equipment.Free((byte)ConquerItem.LeftWeapon))
{
Interfaces.IConquerItem arrow = attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon);
arrow.Durability -= 1;
ItemUsage usage = new ItemUsage(true) { UID = arrow.UID, dwParam = arrow.Durability, ID = ItemUsage.UpdateDurability };
usage.Send(attacker.Owner);
if (arrow.Durability <= 0 || arrow.Durability > 5000)
{
Network.PacketHandler.ReloadArrows(attacker.Owner.Equipment.TryGetItem(ConquerItem.LeftWeapon), attacker.Owner);
}
}
}
if (ServerBase.Kernel.GetDistance(attacker.X, attacker.Y, attackedsob.X, attackedsob.Y) <= ServerBase.Constants.pScreenDistance)
{
uint damage = Game.Attacking.Calculate.Ranged(attacker, attackedsob);
attack.Damage = damage;
ReceiveAttack(attacker, attackedsob, attack, damage, null);
if (damage > attackedsob.Hitpoints)
{
attacker.Owner.IncreaseProficiencyExperience(Math.Min(damage, attackedsob.Hitpoints), 500);
}
else
{
attacker.Owner.IncreaseProficiencyExperience(damage, 500);
}
}
}
}
else
{
attacker.AttackPacket = null;
}
}
#endregion
Scatter code in Handle.cs (For references)
Code:
#region Scatter
case 8001:
{
if (CanUseSpell(spell, attacker.Owner))
{
PrepareSpell(spell, attacker.Owner);
SpellUse suse = new SpellUse(true);
suse.Attacker = attacker.UID;
suse.SpellID = spell.ID;
suse.SpellLevel = spell.Level;
suse.X = X;
suse.Y = Y;
if (attacker.xx == attacker.X && attacker.yy == attacker.Y)
{
attacker.scatter += 1;
if (attacker.scatter > 50)
{
attacker.Owner.Disconnect();
}
}
else
{
attacker.xx = attacker.X;
attacker.yy = attacker.Y;
attacker.scatter = 0;
}
Sector sector = new Sector(attacker.X, attacker.Y, X, Y);
sector.Arrange(spell.Sector, spell.Distance);
foreach (Interfaces.IMapObject _obj in attacker.Owner.Screen.Objects)
{
if (_obj == null)
continue;
if (_obj.MapObjType == MapObjectType.Monster || _obj.MapObjType == MapObjectType.Player)
{
attacked = _obj as Entity;
if (sector.Inside(attacked.X, attacked.Y))
{
if (CanAttack(attacker, attacked, spell, attack.AttackType == Attack.Melee))
{
attack.Effect1 = Attack.AttackEffects1.None;
uint damage = Game.Attacking.Calculate.Ranged(attacker, attacked, spell);
ReceiveAttack(attacker, attacked, attack, damage, spell);
suse.Targets.Add(attacked.UID, damage);
}
}
}
else if (_obj.MapObjType == MapObjectType.SobNpc)
{
attackedsob = _obj as SobNpcSpawn;
if (sector.Inside(attackedsob.X, attackedsob.Y))
{
if (CanAttack(attacker, attackedsob, spell))
{
attack.Effect1 = Attack.AttackEffects1.None;
uint damage = Game.Attacking.Calculate.Ranged(attacker, attackedsob);
suse.Effect1 = attack.Effect1;
if (damage == 0)
damage = 1;
damage = Game.Attacking.Calculate.Percent((int)damage, spell.PowerPercent);
ReceiveAttack(attacker, attackedsob, attack, damage, spell);
suse.Targets.Add(attackedsob.UID, damage);
}
}
}
}
attacker.Owner.SendScreen(suse, true);
}
break;
}
#endregion
SpellUse.cs
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Conquer_Online_Server.Network.GamePackets
{
public class SpellUse : Interfaces.IPacket
{
public enum EffectValue : uint
{
None = 0,
Block = 1,
Penetration = 2,
CriticalStrike = 4,
CriticalBlock = 5,
WoodResist = 40,
MetalResist = 48,
EarthResist = 1,
StudyPoints = 2,
}
public class DamageClass
{
public uint Damage;
public bool Hit;
public static implicit operator uint(DamageClass dmg)
{
return dmg.Damage;
}
public static implicit operator DamageClass(uint dmg)
{
return new DamageClass() { Damage = dmg, Hit = true };
}
}
byte[] Buffer;
public SpellUse(bool Create)
{
if (Create)
{
Buffer = new byte[8 + 20];
Writer.WriteUInt16(20, 0, Buffer);
Writer.WriteUInt16(1105, 2, Buffer);
}
}
public uint Attacker
{
get { return BitConverter.ToUInt32(Buffer, 4); }
set { Writer.WriteUInt32(value, 4, Buffer); }
}
public ushort X
{
get { return BitConverter.ToUInt16(Buffer, 8); }
set { Writer.WriteUInt16(value, 8, Buffer); }
}
public ushort Y
{
get { return BitConverter.ToUInt16(Buffer, 10); }
set { Writer.WriteUInt16(value, 10, Buffer); }
}
public ushort SpellID
{
get { return BitConverter.ToUInt16(Buffer, 12); }
set { Writer.WriteUInt16(value, 12, Buffer); }
}
public ushort SpellLevel
{
get { return BitConverter.ToUInt16(Buffer, 14); }
set { Writer.WriteUInt16(value, 14, Buffer); }
}
public SafeDictionary<uint, DamageClass> Targets = new SafeDictionary<uint, DamageClass>(40);
public SafeDictionary<uint, EffectValue> Effect = new SafeDictionary<uint, EffectValue>(40);
bool constC = false;
public void MakeConst()
{
constC = true;
}
public void Deserialize(byte[] buffer)
{
this.Buffer = buffer;
}
public Attack.AttackEffects1 Effect1
{
get;
set;
}
public Attack.AttackEffects2 Effect2
{
get;
set;
}
public byte[] ToArray()
{
int count = 0;
byte[] buffer = new byte[8 + 20 + 32 + Math.Min((uint)Targets.Count, (uint)30) * 32];
Writer.WriteUInt16((ushort)(20 + 32 + Math.Min((uint)Targets.Count, (uint)30) * 32), 0, buffer);
Writer.WriteUInt16(1105, 2, buffer);
Writer.WriteUInt32(Attacker, 4, buffer);
Writer.WriteUInt16(X, 8, buffer);
Writer.WriteUInt16(Y, 10, buffer);
Writer.WriteUInt16(SpellID, 12, buffer);
Writer.WriteUInt16(SpellLevel, 14, buffer);
Writer.WriteUInt32(Math.Min((uint)Targets.Count, (uint)30), 16, buffer);
ushort offset = 20;
uint uid = 0;
foreach (KeyValuePair<uint, DamageClass> target in Targets.Base)
{
count++;
if (count == 30)
break;
if (constC)
{
if (uid == 0)
uid = target.Key;
Writer.WriteUInt32(uid, offset, buffer);
}
else
Writer.WriteUInt32(target.Key, offset, buffer);
offset += 4;
Writer.WriteUInt32(target.Value.Damage, offset, buffer); offset += 4;
Writer.WriteBoolean(target.Value.Hit, offset, buffer); offset += 4;
if (Effect.ContainsKey(target.Key))
Writer.WriteByte((byte)Effect[target.Key], offset, buffer);
offset += 4;
offset += 16;
}
return buffer;
}
private byte[] toArray()
{
byte[] buffer = new byte[8 + 20 + 32 + Targets.Count * 32];
Writer.WriteUInt16((ushort)(20 + 32 + Targets.Count * 32), 0, buffer);
Writer.WriteUInt16(1105, 2, buffer);
Writer.WriteUInt32(Attacker, 4, buffer);
Writer.WriteUInt16(X, 8, buffer);
Writer.WriteUInt16(Y, 10, buffer);
Writer.WriteUInt16(SpellID, 12, buffer);
Writer.WriteUInt16(SpellLevel, 14, buffer);
Writer.WriteUInt32((uint)Targets.Count, 16, buffer);
ushort offset = 20;
uint uid = 0;
foreach (KeyValuePair<uint, DamageClass> target in Targets.Base)
{
if (constC)
{
if (uid == 0)
uid = target.Key;
Writer.WriteUInt32(uid, offset, buffer);
}
else
Writer.WriteUInt32(target.Key, offset, buffer);
offset += 4;
Writer.WriteUInt32(target.Value.Damage, offset, buffer); offset += 4;
Writer.WriteBoolean(target.Value.Hit, offset, buffer); offset += 4;
Writer.WriteBoolean(true, offset, buffer); offset += 4;//critical...
offset += 16;
}
return buffer;
}
public void Send(Client.GameState client)
{
client.Send(Buffer);
}
}
}
I forgot to tell it, My source version is 5530.
If you need any more infos, ask me.
Thanks again
|
|
|
10/30/2013, 16:39
|
#7
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 950
|
Did you debug and breakpoint?
|
|
|
10/30/2013, 17:04
|
#8
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
Quote:
Originally Posted by Super Aids
Did you debug and breakpoint?
|
I didn't use breakpoints since I don't know how to implement & use them at the moment but I'll learn it so I can more easily identify and fix bugs that occurs when x movement/packet is currently processing.
|
|
|
10/30/2013, 18:20
|
#9
|
elite*gold: 0
Join Date: May 2011
Posts: 648
Received Thanks: 413
|
|
|
|
10/30/2013, 18:52
|
#10
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 950
|
Fang made a thread about it.
And Yuki one thing.
Code:
if (C.MyChar.Mining)
{
C.MyChar.Mining = false;
}
Could just be:
Code:
C.MyChar.Mining = false;
No need to actually do the check.
|
|
|
10/30/2013, 22:57
|
#11
|
elite*gold: 0
Join Date: Feb 2006
Posts: 726
Received Thanks: 271
|
I would guess that the following line is returning false in the scatter case...
if (CanUseSpell(spell, attacker.Owner))
Hard to say for sure though
|
|
|
10/30/2013, 23:34
|
#12
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
Thanks Yuki I didn't know it was that easy xD I still can't figure out why this bug is happening it's getting me crazy..
@Aceking the scatter case is only a reference because every ranged skills have this bug so it's probably deeper than that.
|
|
|
10/31/2013, 00:40
|
#13
|
elite*gold: 0
Join Date: Feb 2006
Posts: 726
Received Thanks: 271
|
Quote:
Originally Posted by elhermanos
Thanks Yuki I didn't know it was that easy xD I still can't figure out why this bug is happening it's getting me crazy..
@Aceking the scatter case is only a reference because every ranged skills have this bug so it's probably deeper than that.
|
Yes your correct, every range spell will have the same bug if that bug lies within the CANUSE method.
Every spell will call that method, checking to see if they can use that spell.
You can breakpoint it, and follow it through for each attack....
Or a simple way to know if its making it through that section is to add something like write to console, or send a system message right after that call.
If you watch the client kill all the monsters without the effect, and that message isn't sent....then you know thats at least part of the problem and can start to work your way back....
I dont recommend doing it that way, as breakpointing is always the best method.....but its a pretty cheap way of going about it....
|
|
|
10/31/2013, 03:40
|
#14
|
elite*gold: 0
Join Date: Aug 2010
Posts: 992
Received Thanks: 1,110
|
Try shifting the targets count in the packet like so...
PHP Code:
Writer.WriteUInt32(Math.Min((uint)Targets.Count, (uint)30) << 8, 16, buffer);
It applies to the current patch clients but i am not sure about 5530.
|
|
|
11/01/2013, 01:08
|
#15
|
elite*gold: 15
Join Date: Dec 2008
Posts: 332
Received Thanks: 137
|
Quote:
Originally Posted by { Angelius }
Try shifting the targets count in the packet like so...
PHP Code:
Writer.WriteUInt32(Math.Min((uint)Targets.Count, (uint)30) << 8, 16, buffer);
It applies to the current patch clients but i am not sure about 5530.
|
Didn't work and added more bugs :S
Again, Thanks to everyone that are trying to help me out.
|
|
|
 |
|
Similar Threads
|
Entities beim Hammer Editor
10/14/2011 - Counter-Strike - 0 Replies
Einen schönen Tag,
ich habe mich mal an das Mappen probiert und soweit klappt alles gut, nur wenn es dann darum geht den Spawn für die Terroristen und die Counterterroristen zu setzen klappt garnichts mehr. Da diese zwei entities nicht in der Liste vorhanden sind. Und jetzt bräuchte ich euren Rat, wie bekomme ich diese Entities, da ohne sie eine Map nunmal nicht spielbar ist ...
Ich hoffe das mir jemand helfen kann.
Mfg ~Bananenwerfer
|
I have a problem spawning entities
07/28/2011 - CO2 Programming - 4 Replies
what is The problem
Heroes can be Spawned at the 1st time i set it's locations in but if i moved +18 Coords and tried to re-spawn again it doesn't spawn while the packet being send to all the Entities with the right location .
what am trying to do is:
getting all the NearByEntities and re-spawn it between range 18..
what's happening:
is when i set the location for the 1st time i will be able to spawn and re-spawn within 18 coords where i located , if i moved out my location +18 coords...
|
Entities spwan/w.e sure take a look and see if you can help
07/01/2011 - CO2 Private Server - 6 Replies
hello everyone .
what is the best way to do the clients/monsters/npc's spawns
like when a player jumps what is the best way to spawn the in range entities .
i have tried to store the entities in some kind of dictionary (Local entities) and spawn them on jumping/walking ...> slow
i have stored every single valid X/Y in the game maps as a key with a Dictionary associated to that key as a value and stored the entities in that dictionary depending on the X/Y and spawned them on...
|
Spawn Entities, Current Patch
03/25/2011 - CO2 Private Server - 18 Replies
EDIT:
Nevermind, my packet was off a few bytes :P
Has spawning entities in the lastest patch changed?
Entities (ex: Players) don't spawn to each other on my source since the latest patch.
|
entities.cs problem
10/13/2008 - CO2 Programming - 2 Replies
hi, i have a problem with entities.cs when i start my server it loads everyting almost all mobs i have but when he is on SpawnALLMobs it give an error at line:217
error=System.NullReferenceException: Object reference not set to an instance of an object.
line:218 is DataBase.Mobs = null;
now you know where to look just above line:218
this is what i have:
public static void SpawnAllMobs()
{
try
{
|
All times are GMT +1. The time now is 06:46.
|
|