private static void SendSub(WorldObject obj, object[] args) { // Arguments: // - source obj // - Packet // - ESendTarget Character source = args[0] as Character; Packet p = args[1] as Packet; ESendTarget sendType = (ESendTarget)args[2]; Character target = (obj as Character); // Both needs to be player (to receive packets) if (source == null || target == null) { return; } switch (sendType) { case ESendTarget.AreaWithoutSelf: if (source.ID == target.ID) { return; } break; case ESendTarget.AreaWithoutChatrooms: if (target.Status.ChatID is WorldID || source.ID == target.ID) { return; } break; case ESendTarget.AreaWithoutOwnChatrooms: if (target.Status.ChatID is WorldID || (source.Status.ChatID is WorldID && source.Status.ChatID == target.Status.ChatID)) { return; } break; } target.Account.Netstate.Send(p); return; }
/// Validates and processes global messages /// 008C/00F3 -1: <packet len>.W <text>.?B (<name> : <message>) 00 public static void GlobalMessage(NetState state, PacketReader reader) { if (state.IsValid(EAccountState.World) == false) { state.Disconnect(); return; } short baseLength = (short)(reader.ReadInt16() - 4); string baseMessage = reader.ReadString(baseLength); string username, message; if (ChatHelper.ValidateMessage(state, baseMessage, out username, out message) == false) { return; } // Check is implemented, but no commands yet.. xD if (PlayerCommandHelper.IsCommand(message) == true) { PlayerCommandHelper.Execute(state, message); return; } // Send packet to all players in the chatroom or in hearable area // Note: yes, the Client needs the full String "Name : Message" // and dosnt take the name from the source.. // so we just use the original received string ESendTarget target = (state.ActiveChar.Status.ChatID is WorldID ? ESendTarget.ChatWithoutSelf : ESendTarget.HearableAreaWithoutChatrooms); World.Send(new WorldChatMessage(state.ActiveChar, baseMessage), state.ActiveChar, target); // Send packet to himself // Note: the base string "Name : Message" is used again.. World.Send(new WorldMessageOverHead(baseMessage), state.ActiveChar, ESendTarget.Self); // TODO: // - trigger listening npc's // - log chat }
public static void Send(Packet p, WorldObject source, ESendTarget target) { if (target != ESendTarget.AllClients && target != ESendTarget.ChatMainchat) { if (source == null) { ServerConsole.ErrorLine("World.Send: WorldObject (source) cant be null on type " + target + "!"); return; } } Rectangle2D area; switch (target) { case ESendTarget.Self: if (source is Character && (source as Character).Account.Netstate != null) { (source as Character).Account.Netstate.Send(p); } break; case ESendTarget.AllClients: World.SendAllClients(p); break; case ESendTarget.AllSameMap: // Source must have a map/is moveable if (source is WorldObjectUnit) { foreach (MapBlock block in (source as WorldObjectUnit).Map.Blocks) { foreach (WorldObject obj in block.Values) { if (obj is Character) { (obj as Character).Account.Netstate.Send(p); } } } } break; case ESendTarget.Area: case ESendTarget.AreaWithoutOwnChatrooms: case ESendTarget.AreaWithoutChatrooms: case ESendTarget.AreaWithoutSelf: //if (sd && bl->prev == NULL) //Otherwise source misses the packet // TODO: what means that? how exactly do they using ->prev and ->next pointer? if ((source is Character) && (target == ESendTarget.Area || target == ESendTarget.AreaWithoutOwnChatrooms)) { (source as Character).Account.Netstate.Send(p); } if (source is Character) { area = new Rectangle2D((source as Character).Location.X - Global.AREA_SIZE, (source as Character).Location.Y - Global.AREA_SIZE, (source as Character).Location.X + Global.AREA_SIZE, (source as Character).Location.Y + Global.AREA_SIZE, true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, target }); } break; case ESendTarget.HearableAreaWithoutChatrooms: if (source is Character) { area = new Rectangle2D((source as Character).Location.X - (Global.AREA_SIZE - 5), (source as Character).Location.Y - (Global.AREA_SIZE - 5), (source as Character).Location.X + (Global.AREA_SIZE - 5), (source as Character).Location.Y + (Global.AREA_SIZE - 5), true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, ESendTarget.AreaWithoutChatrooms }); } break; } }
public static void Send(Packet p, WorldObject source, ESendTarget target) { if (target != ESendTarget.AllClients && target != ESendTarget.ChatMainchat) { if (source == null) { ServerConsole.ErrorLine("World.Send: WorldObject (source) cant be null on type " + target + "!"); return; } } Rectangle2D area; switch (target) { case ESendTarget.Self: if (source is Character && (source as Character).Account.Netstate != null) { (source as Character).Account.Netstate.Send(p); } break; case ESendTarget.AllClients: World.SendAllClients(p); break; case ESendTarget.AllSameMap: // Source must have a map/is moveable if (source is WorldObjectUnit) { foreach (MapBlock block in (source as WorldObjectUnit).Map.Blocks) { foreach (WorldObject obj in block.Values) { if (obj is Character) { (obj as Character).Account.Netstate.Send(p); } } } } break; case ESendTarget.Area: case ESendTarget.AreaWithoutOwnChatrooms: case ESendTarget.AreaWithoutChatrooms: case ESendTarget.AreaWithoutSelf: //if (sd && bl->prev == NULL) //Otherwise source misses the packet // TODO: what means that? how exactly do they using ->prev and ->next pointer? if ((source is Character) && (target == ESendTarget.Area || target == ESendTarget.AreaWithoutOwnChatrooms)) { (source as Character).Account.Netstate.Send(p); } if (source is Character) { area = new Rectangle2D((source as Character).Location.X - Global.AREA_SIZE, (source as Character).Location.Y - Global.AREA_SIZE, (source as Character).Location.X + Global.AREA_SIZE, (source as Character).Location.Y + Global.AREA_SIZE, true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, target }); } break; case ESendTarget.HearableAreaWithoutChatrooms: if (source is Character) { area = new Rectangle2D((source as Character).Location.X - (Global.AREA_SIZE - 5), (source as Character).Location.Y - (Global.AREA_SIZE - 5), (source as Character).Location.X + (Global.AREA_SIZE - 5), (source as Character).Location.Y + (Global.AREA_SIZE - 5), true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, ESendTarget.AreaWithoutChatrooms }); } break; } }