/// <summary> /// </summary> /// <param name="ch"> /// </param> /// <param name="statsToUpdate"> /// </param> public static void SendBulk(Character ch, Dictionary<int, uint> statsToUpdate) { if (statsToUpdate.Count == 0) { return; } var toPlayfield = new List<int>(); foreach (KeyValuePair<int, uint> keyValuePair in statsToUpdate) { if (ch.Stats[keyValuePair.Key].AnnounceToPlayfield) { toPlayfield.Add(keyValuePair.Key); } } var stats = new List<GameTuple<CharacterStat, uint>>(); foreach (KeyValuePair<int, uint> keyValuePair in statsToUpdate) { if (toPlayfield.Contains(keyValuePair.Key)) { stats.Add( new GameTuple<CharacterStat, uint> { Value1 = (CharacterStat)keyValuePair.Key, Value2 = keyValuePair.Value }); } } /* announce to playfield? */ if (toPlayfield.Any() == false) { return; } var message = new StatMessage { Identity = ch.Identity, Stats = stats.ToArray() }; ch.Playfield.AnnounceOthers(message, ch.Identity); }
/// <summary> /// </summary> /// <param name="character"> /// </param> public static void AnnounceAppearanceUpdate(Character character) { var message = new AppearanceUpdateMessage { Identity = character.Identity, Unknown = 0x00, }; List<AOMeshs> meshs; int counter; bool socialonly; bool showsocial; /* bool showhelmet; bool LeftPadVisible; bool RightPadVisible; bool DoubleLeftPad; bool DoubleRightPad; int TexturesCount; int HairMeshValue; int WeaponMeshRightValue; int WeaponMeshLeftValue; uint HeadMeshBaseValue; int HeadMeshValue; int BackMeshValue; int ShoulderMeshRightValue; */ // int ShoulderMeshRightValue; int VisualFlags; int PlayField; /* int OverrideTextureHead; int OverrideTextureWeaponRight; int OverrideTextureWeaponLeft; int OverrideTextureShoulderpadRight; int OverrideTextureShoulderpadLeft; int OverrideTextureBack; int OverrideTextureAttractor; */ var textures = new List<AOTextures>(); var socialTab = new Dictionary<int, int>(); lock (character) { VisualFlags = character.Stats["VisualFlags"].Value; socialonly = (character.Stats["VisualFlags"].Value & 0x40) > 0; showsocial = (character.Stats["VisualFlags"].Value & 0x20) > 0; /* showhelmet = ((character.Stats.VisualFlags.Value & 0x4) > 0); LeftPadVisible = ((character.Stats.VisualFlags.Value & 0x1) > 0); RightPadVisible = ((character.Stats.VisualFlags.Value & 0x2) > 0); DoubleLeftPad = ((character.Stats.VisualFlags.Value & 0x8) > 0); DoubleRightPad = ((character.Stats.VisualFlags.Value & 0x10) > 0); HairMeshValue = character.Stats.HairMesh.Value; TexturesCount = character.Textures.Count; HairMeshValue = character.Stats.HairMesh.Value; WeaponMeshRightValue = character.Stats.WeaponMeshRight.Value; WeaponMeshLeftValue = character.Stats.WeaponMeshLeft.Value; HeadMeshBaseValue = character.Stats.HeadMesh.StatBaseValue; HeadMeshValue = character.Stats.HeadMesh.Value; BackMeshValue = character.Stats.BackMesh.Value; ShoulderMeshRightValue = character.Stats.ShoulderMeshRight.Value; */ // ShoulderMeshLeftValue = character.Stats.ShoulderMeshLeft.Value; /* OverrideTextureHead = character.Stats.OverrideTextureHead.Value; OverrideTextureWeaponRight = character.Stats.OverrideTextureWeaponRight.Value; OverrideTextureWeaponLeft = character.Stats.OverrideTextureWeaponLeft.Value; OverrideTextureShoulderpadRight = character.Stats.OverrideTextureShoulderpadRight.Value; OverrideTextureShoulderpadLeft = character.Stats.OverrideTextureShoulderpadLeft.Value; OverrideTextureBack = character.Stats.OverrideTextureBack.Value; OverrideTextureAttractor = character.Stats.OverrideTextureAttractor.Value; */ PlayField = character.Playfield.Identity.Instance; foreach (int num in character.SocialTab.Keys) { socialTab.Add(num, character.SocialTab[num]); } foreach (AOTextures texture in character.Textures) { textures.Add(new AOTextures(texture.place, texture.Texture)); } meshs = MeshLayers.GetMeshs(character, showsocial, socialonly); } var texturesToSend = new List<Texture>(); var aotemp = new AOTextures(0, 0); for (counter = 0; counter < 5; counter++) { aotemp.Texture = 0; aotemp.place = counter; int c2; for (c2 = 0; c2 < textures.Count; c2++) { if (textures[c2].place == counter) { aotemp.Texture = textures[c2].Texture; break; } } if (showsocial) { if (socialonly) { aotemp.Texture = socialTab[counter]; } else { if (socialTab[counter] != 0) { aotemp.Texture = socialTab[counter]; } } } texturesToSend.Add(new Texture { Place = aotemp.place, Id = aotemp.Texture, Unknown = 0 }); } message.Textures = texturesToSend.ToArray(); message.Meshes = meshs.Select( mesh => new Mesh { Position = (byte)mesh.Position, Id = (uint)mesh.Mesh, OverrideTextureId = mesh.OverrideTexture, Layer = (byte)mesh.Layer }).ToArray(); message.VisualFlags = (short)VisualFlags; character.Playfield.Announce(message); }
/// <summary> /// </summary> /// <param name="character"> /// </param> /// <param name="stat"> /// </param> /// <param name="value"> /// </param> /// <param name="announce"> /// </param> public static void Send(Character character, int stat, int value, bool announce) { Send((Client)character.Client, stat, value, announce); }
/// <summary> /// </summary> /// <param name="functionName"> /// </param> /// <param name="character"> /// </param> public void CallMethod(string functionName, Character character) { foreach (Assembly assembly in this.multipleDllList) { foreach (KeyValuePair<string, Type> kv in this.scriptList) { if (kv.Key.IndexOf(":") >= 0) { if (kv.Key.Substring(kv.Key.IndexOf(":", StringComparison.Ordinal)) == ":" + functionName) { IAOScript aoScript = (IAOScript) assembly.CreateInstance( kv.Key.Substring(0, kv.Key.IndexOf(":", StringComparison.Ordinal))); if (aoScript != null) { kv.Value.InvokeMember( functionName, BindingFlags.Default | BindingFlags.InvokeMethod, null, aoScript, new object[] { character }, CultureInfo.InvariantCulture); } } } } } }
/// <summary> /// </summary> /// <param name="character"> /// </param> /// <returns> /// </returns> public static SimpleCharFullUpdateMessage ConstructMessage(Character character) { // Character Variables bool socialonly; bool showsocial; int charPlayfield; AOCoord charCoord; Identity charId; Quaternion charHeading; uint sideValue; uint fatValue; uint breedValue; uint sexValue; uint raceValue; string charName; int charFlagsValue; int accFlagsValue; int expansionValue; int currentNano; int currentHealth; uint strengthBaseValue; uint staminaBaseValue; uint agilityBaseValue; uint senseBaseValue; uint intelligenceBaseValue; uint psychicBaseValue; string firstName; string lastName; int orgNameLength; string orgName; int levelValue; int healthValue; int losHeight; int monsterData; int monsterScale; int visualFlags; int currentMovementMode; uint runSpeedBaseValue; int texturesCount; int headMeshValue; // NPC Values int NPCFamily; var socialTab = new Dictionary<int, int>(); var textures = new List<AOTextures>(); List<AOMeshs> meshs; var nanos = new List<AONano>(); lock (character) { socialonly = (character.Stats["VisualFlags"].Value & 0x40) > 0; showsocial = (character.Stats["VisualFlags"].Value & 0x20) > 0; charPlayfield = character.Playfield.Identity.Instance; charCoord = character.Coordinates; charId = character.Identity; charHeading = character.Heading; sideValue = character.Stats["Side"].BaseValue; fatValue = character.Stats["Fatness"].BaseValue; breedValue = character.Stats["Breed"].BaseValue; sexValue = character.Stats["Sex"].BaseValue; raceValue = character.Stats["Race"].BaseValue; charName = character.Name; charFlagsValue = character.Stats["Flags"].Value; accFlagsValue = character.Stats["AccountFlags"].Value; expansionValue = character.Stats["Expansion"].Value; currentNano = character.Stats["CurrentNano"].Value; strengthBaseValue = character.Stats["Strength"].BaseValue; staminaBaseValue = character.Stats["Strength"].BaseValue; agilityBaseValue = character.Stats["Strength"].BaseValue; senseBaseValue = character.Stats["Strength"].BaseValue; intelligenceBaseValue = character.Stats["Strength"].BaseValue; psychicBaseValue = character.Stats["Strength"].BaseValue; firstName = character.FirstName; lastName = character.LastName; orgNameLength = character.OrganizationName.Length; orgName = character.OrganizationName; levelValue = character.Stats["Level"].Value; healthValue = character.Stats["Life"].Value; monsterData = character.Stats["MonsterData"].Value; monsterScale = character.Stats["MonsterScale"].Value; visualFlags = character.Stats["VisualFlags"].Value; currentMovementMode = character.Stats["CurrentMovementMode"].Value; runSpeedBaseValue = character.Stats["RunSpeed"].BaseValue; texturesCount = character.Textures.Count; headMeshValue = character.Stats["HeadMesh"].Value; foreach (int num in character.SocialTab.Keys) { socialTab.Add(num, character.SocialTab[num]); } foreach (AOTextures at in character.Textures) { textures.Add(new AOTextures(at.place, at.Texture)); } meshs = MeshLayers.GetMeshs(character, showsocial, socialonly); foreach (AONano nano in character.ActiveNanos) { var tempNano = new AONano(); tempNano.ID = nano.ID; tempNano.Instance = nano.Instance; tempNano.NanoStrain = nano.NanoStrain; tempNano.Nanotype = nano.Nanotype; tempNano.Time1 = nano.Time1; tempNano.Time2 = nano.Time2; tempNano.Value3 = nano.Value3; nanos.Add(tempNano); } losHeight = character.Stats["LosHeight"].Value; NPCFamily = character.Stats["NpcFamily"].Value; currentHealth = character.Stats["Health"].Value; } var scfu = new SimpleCharFullUpdateMessage(); // affected identity scfu.Identity = charId; scfu.Version = 57; // SCFU packet version (57/0x39) scfu.Flags = SimpleCharFullUpdateFlags.None; // Try setting to 0x042062C8 if you have problems (old value) scfu.Flags |= SimpleCharFullUpdateFlags.HasPlayfieldId; // Has Playfield ID scfu.PlayfieldId = charPlayfield; // playfield if (character.FightingTarget.Instance != 0) { scfu.Flags |= SimpleCharFullUpdateFlags.HasFightingTarget; scfu.FightingTarget = new Identity { Type = character.FightingTarget.Type, Instance = character.FightingTarget.Instance }; } // Coordinates scfu.Coordinates = new Vector3 { X = charCoord.x, Y = charCoord.y, Z = charCoord.z }; // Heading Data scfu.Flags |= SimpleCharFullUpdateFlags.HasHeading; scfu.Heading = new SmokeLounge.AOtomation.Messaging.GameData.Quaternion { W = charHeading.wf, X = charHeading.xf, Y = charHeading.yf, Z = charHeading.zf }; // Race scfu.Appearance = new Appearance { Side = (Side)sideValue, Fatness = (Fatness)fatValue, Breed = (Breed)breedValue, Gender = (Gender)sexValue, Race = raceValue }; // appearance // Name scfu.Name = charName; scfu.CharacterFlags = (CharacterFlags)charFlagsValue; // Flags scfu.AccountFlags = (short)accFlagsValue; scfu.Expansions = (short)expansionValue; bool isNpc = character is NonPlayerCharacter; if (isNpc) { // Are we a NPC (i think anyway)? So far this is _NOT_ used at all scfu.Flags |= SimpleCharFullUpdateFlags.IsNpc; var snpc = new SimpleNpcInfo { Family = (short)NPCFamily, LosHeight = (short)losHeight }; scfu.CharacterInfo = snpc; } else { // Are we a player? var spc = new SimplePcInfo(); spc.CurrentNano = (uint)currentNano; // CurrentNano spc.Team = 0; // team? spc.Swim = 5; // swim? // The checks here are to prevent the client doing weird things if the character has really large or small base attributes spc.StrengthBase = (short)Math.Min(strengthBaseValue, short.MaxValue); // Strength spc.AgilityBase = (short)Math.Min(agilityBaseValue, short.MaxValue); // Agility spc.StaminaBase = (short)Math.Min(staminaBaseValue, short.MaxValue); // Stamina spc.IntelligenceBase = (short)Math.Min(intelligenceBaseValue, short.MaxValue); // Intelligence spc.SenseBase = (short)Math.Min(senseBaseValue, short.MaxValue); // Sense spc.PsychicBase = (short)Math.Min(psychicBaseValue, short.MaxValue); // Psychic if (scfu.CharacterFlags.HasFlag(CharacterFlags.HasVisibleName)) { // has visible names? (Flags) spc.FirstName = firstName; spc.LastName = lastName; } if (orgNameLength != 0) { scfu.Flags |= SimpleCharFullUpdateFlags.HasOrgName; // Has org name data spc.OrgName = orgName; } scfu.CharacterInfo = spc; } // Level scfu.Level = (short)levelValue; if (scfu.Level > sbyte.MaxValue) { scfu.Flags |= SimpleCharFullUpdateFlags.HasExtendedLevel; } // Health scfu.Health = (uint)healthValue; if (scfu.Health <= short.MaxValue) { scfu.Flags |= SimpleCharFullUpdateFlags.HasSmallHealth; } scfu.HealthDamage = healthValue - currentHealth; if (scfu.HealthDamage <= byte.MaxValue) { scfu.Flags |= SimpleCharFullUpdateFlags.HasSmallHealthDamage; } // If player is in grid or fixer grid // make him/her/it a nice upside down pyramid if ((charPlayfield == 152) || (charPlayfield == 4107)) { scfu.MonsterData = 99902; } else { scfu.MonsterData = (uint)monsterData; // Monsterdata } scfu.MonsterScale = (short)monsterScale; // Monsterscale scfu.VisualFlags = (short)visualFlags; // VisualFlags scfu.VisibleTitle = 0; // visible title? // 42 bytes long scfu.Unknown1 = new byte[] { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, (byte)currentMovementMode, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (headMeshValue != 0) { scfu.Flags |= SimpleCharFullUpdateFlags.HasHeadMesh; // Has HeadMesh Flag scfu.HeadMesh = (uint?)headMeshValue; // Headmesh } // Runspeed scfu.RunSpeedBase = (short)runSpeedBaseValue; if (runSpeedBaseValue > sbyte.MaxValue) { scfu.Flags |= SimpleCharFullUpdateFlags.HasExtendedRunSpeed; } scfu.ActiveNanos = (from nano in nanos select new ActiveNano { NanoId = nano.ID, NanoInstance = nano.Instance, Time1 = nano.Time1, Time2 = nano.Time2 }).ToArray(); // Texture/Cloth Data var scfuTextures = new List<Texture>(); var aotemp = new AOTextures(0, 0); for (int c = 0; c < 5; c++) { aotemp.Texture = 0; aotemp.place = c; for (int c2 = 0; c2 < texturesCount; c2++) { if (textures[c2].place != c) { continue; } aotemp.Texture = textures[c2].Texture; break; } if (showsocial) { if (socialonly) { aotemp.Texture = socialTab[c]; } else { if (socialTab[c] != 0) { aotemp.Texture = socialTab[c]; } } } scfuTextures.Add(new Texture { Place = aotemp.place, Id = aotemp.Texture, Unknown = 0 }); } scfu.Textures = scfuTextures.ToArray(); // End Textures // ############ // # Meshs // ############ scfu.Meshes = (from aoMesh in meshs select new Mesh { Position = (byte)aoMesh.Position, Id = (uint)aoMesh.Mesh, OverrideTextureId = aoMesh.OverrideTexture, Layer = (byte)aoMesh.Layer }).ToArray(); // End Meshs scfu.Flags2 = 0; // packetFlags2 scfu.Unknown2 = 0; return scfu; }
/// <summary> /// </summary> /// <param name="character"> /// </param> /// <param name="receiver"> /// </param> public static void SendToOne(Character character, Client receiver) { SimpleCharFullUpdateMessage message = ConstructMessage(character); receiver.SendCompressed(message); }
/// <summary> /// </summary> /// <param name="charId"> /// </param> /// <exception cref="Exception"> /// </exception> public void CreateCharacter(int charId) { this.character = new Character(new Identity { Type = IdentityType.CanbeAffected, Instance = charId }, this); IEnumerable<DBCharacter> daochar = CharacterDao.GetById(charId); if (daochar.Count() == 0) { throw new Exception("Character " + charId.ToString() + " not found."); } if (daochar.Count() > 1) { throw new Exception( daochar.Count().ToString() + " Characters with id " + charId.ToString() + " found??? Check Database setup!"); } DBCharacter character = daochar.First(); this.character.Name = character.Name; this.character.LastName = character.LastName; this.character.FirstName = character.FirstName; this.character.Coordinates = new AOCoord(character.X, character.Y, character.Z); this.character.Heading = new Quaternion( character.HeadingX, character.HeadingY, character.HeadingZ, character.HeadingW); this.character.Playfield = this.server.PlayfieldById(character.Playfield); this.Playfield = this.character.Playfield; this.Playfield.Entities.Add(this.character); this.character.Stats.Read(); this.character.BaseInventory.Read(); }