public EventEngine(MapleCharacter starter, string script, int recreateMap = -1, bool skipSpawn = false) { Starter = starter; ChannelId = Starter.Client.Channel; if (!(DataBuffer.EventScripts.TryGetValue(script, out EventType) && EventType != null)) { return; } EventInstance = ScriptActivator.CreateScriptInstance(EventType, script, starter) as EventScript; if (EventInstance == null) { string error = string.Format("Error loading {0} {1}", "EventScript", script); ServerConsole.Error(error); FileLogging.Log("Event scripts", error); return; } RecreatedMap = recreateMap != -1; EventInstance.OnFinish += new Action(FinishEvent); EventInstance.OnSpawnMobs += new Action <int, int, int, int>(SpawnMobs); EventInstance.OnRandomSpawnMobs += new Action <int, int, Point, Point>(RandomSpawnMobs); if (RecreatedMap) { EventMap = new MapleEvent(recreateMap, DataBuffer.GetMapById(recreateMap), skipSpawn); EventId = Program.RegisterEvent(EventMap); if (Starter != null) { AddCharacter(Starter); } } }
public bool ExecuteScriptForNpc() { if (ScriptInstance == null) { return(false); } try { if (IsShop) { Client.SendPacket(Packets.ShowShop((ShopScript)ScriptInstance, NpcId)); } ScriptInstance.Execute(); return(true); } catch (Exception ex) { string errorString = string.Format("NpcId: {0}\r\nState: {1}\r\n Selection: {2}\r\nException: {3}", NpcId, ScriptInstance.State, ScriptInstance.Selection, ex); ServerConsole.Debug("Npc script execution error: " + errorString); FileLogging.Log("Npc scripts", errorString); SendOk("An error occured, please report this on the forums\r\nNpcId: " + NpcId); Dispose(); return(false); } }
internal void RecvPacket(PacketReader packet) { try { RecvPacketHandler.Handle(packet, this); } catch (Exception e) { ServerConsole.Error(e.ToString()); FileLogging.Log("PacketExceptions.txt", e.ToString()); } }
public static void HandleReturnScroll(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); pr.Skip(2); //Unk int itemId = pr.ReadInt(); if (!chr.Inventory.HasItem(itemId)) { return; } WzConsume item = DataBuffer.GetItemById(itemId) as WzConsume; if (item == null) { return; } if (item.MoveTo > 0) { int toMap = 0; toMap = item.MoveTo == 999999999 ? chr.Map.ReturnMap : item.MoveTo; if (toMap != 0) { MapleMap map = Program.GetChannelServer(c.Channel).GetMap(toMap); if (map == null || map.PortalScrollLimit) { return; } if (chr.Inventory.RemoveItemsById(itemId, 1)) { chr.ChangeMap(toMap); } } } else { string msg = "Unhandled return scroll: " + itemId; ServerConsole.Warning(msg); FileLogging.Log("Unhandled items", msg); chr.EnableActions(); } }
public static void Handle(MapleClient c, PacketReader pr) { try { if (c.Account == null) { c.Disconnect("Client is not logged in to an account"); return; } string pic = pr.ReadMapleString(); int characterId = pr.ReadInt(); pr.Skip(1); string macs = pr.ReadMapleString(); string clientid = pr.ReadMapleString(); if (c.Account.CheckPic(pic) && c.Account.HasCharacter(characterId) && Program.ChannelServers.ContainsKey(c.Channel)) { ushort port = Program.ChannelServers[c.Channel].Port; c.Account.MigrationData.CharacterId = characterId; c.Account.MigrationData.Character = MapleCharacter.LoadFromDatabase(characterId, false); c.Account.MigrationData.Character.Hidden = c.Account.IsGM; Program.EnqueueMigration(characterId, c.Account.MigrationData); c.SendPacket(ChannelIpPacket(port, characterId)); } else { //Incorrect Pic PacketWriter pw = new PacketWriter(); pw.WriteHeader(SendHeader.PICResponse); pw.WriteByte(0x14); c.SendPacket(pw); } } catch (Exception ex) { ServerConsole.Error(ex.ToString()); FileLogging.Log("Character loading", ex.ToString()); c.SendPacket(MapleCharacter.ServerNotice("Error loading character", 1)); /*PacketWriter pw = new PacketWriter(); * pw.WriteHeader(SendHeaders.PICResponse); * pw.WriteByte(0x15); * c.SendPacket(pw);*/ } }
public static void Handle(MapleClient c, PacketReader pr) { if (pr.Available > 8) { short type = pr.ReadShort(); string typeString = "Unknown"; if (type == 0x01) { typeString = "SendBackupPacket"; } else if (type == 0x02) { typeString = "Crash Report"; } else if (type == 0x03) { typeString = "Exception"; } int errorType = pr.ReadInt(); //if (errorType == 0) //Usually some bounceback to login //return; short dataLength = pr.ReadShort(); pr.Skip(4); int header = pr.ReadShort(); string headerName = Enum.GetName(typeof(SendHeader), header) + String.Format(" : {0}", header.ToString("X")); string accountName = c.Account.Name; string playerName = "N/A (not logged in yet)"; if (c.Account.Character != null) { playerName = c.Account.Character.Name; //TODO: map id } string remainingBytes = pr.ToString(true); string errorString = String.Format("Error Type: {0}\r\nData Length: {1}\r\nError for player:{2} - account: {3}\r\nHeader: {4}\r\nData: {5}", typeString, dataLength, playerName, accountName, headerName, remainingBytes); FileLogging.Log("ErrorCodes.txt", errorString); ServerConsole.Warning("Error 38 caused by: " + headerName); } }
public NpcEngine(MapleClient c, int id) { Client = c; NpcId = id; Type npcT; if (DataBuffer.NpcScripts.TryGetValue(NpcId, out npcT) && npcT != null) { ScriptInstance = ScriptActivator.CreateScriptInstance(npcT, npcT.ToString(), c.Account.Character) as NpcScript; if (ScriptInstance == null) { string error = string.Format("Error loading {0} {1}", "NpcScript", npcT.ToString()); ServerConsole.Error(error); FileLogging.Log("Npc scripts", error); return; } if (ScriptInstance.IsShop) { IsShop = true; } else { ScriptInstance.SendOk = new Action <string>(SendOk); ScriptInstance.SendNext = new Action <string>(SendNext); ScriptInstance.SendPrev = new Action <string>(SendPrev); ScriptInstance.SendNextPrev = new Action <string>(SendNextPrev); ScriptInstance.SendSimple = new Action <string>(SendSimple); ScriptInstance.EndChat = new Action(Dispose); ScriptInstance.SendYesNo = new Action <string>(SendYesNo); ScriptInstance.SendAskText = new Action <string, int, int, string>(SendAskText); } } else { SendOk(string.Format(@"An error has occured in my script. Please report this as a bug\r\nNpcId: {0}", NpcId)); ServerConsole.Debug(string.Format(@"Missing script for NPC: {0}", NpcId)); ScriptInstance = null; c.Account.Character.EnableActions(); } }
public static void EnterScriptedPortal(WzMap.Portal portal, MapleCharacter character) { if (!string.IsNullOrEmpty(portal.Script)) { Type portalScriptType; if (DataBuffer.PortalScripts.TryGetValue(portal.Script, out portalScriptType) && portalScriptType != null) { PortalScript scriptInstance = Activator.CreateInstance(portalScriptType) as PortalScript; if (scriptInstance == null) { string error = string.Format("Error loading {0} {1}", "PortalScript", portal.Script); ServerConsole.Error(error); FileLogging.Log("Portal scripts", error); return; } scriptInstance.Character = new ScriptCharacter(character, portal.Script); try { scriptInstance.Execute(); } catch (Exception e) { string error = string.Format("Script: {0} error: {1}", portal.Script, e); FileLogging.Log("Portal scripts", error); ServerConsole.Debug("Portal script execution error: " + error); character.EnableActions(); } } else { character.SendBlueMessage(string.Format("This portal is not coded yet (mapId: {0}, portalId: {1}, script name: {2})", character.MapId, portal.Id, portal.Script)); character.EnableActions(); } } else { character.EnableActions(); } }
public static List <MapleMovementFragment> Parse(PacketReader pr) { List <MapleMovementFragment> movementList = new List <MapleMovementFragment>(); byte movements = pr.ReadByte(); for (int i = 0; i < movements; i++) { byte type = pr.ReadByte(); switch (type)//completely changed by alonevampire { case 0x00: case 0x08: case 0x0F: case 0x12: case 0x17: case 0x3A: case 0x3B: case 0x3C: { Point position = pr.ReadPoint(); Point wobble = pr.ReadPoint(); short fh = pr.ReadShort(); short fhFallStart = 0; Point offset = new Point(); if (type == 0xF) { fhFallStart = pr.ReadShort(); } if (type != 0x3A) { offset = pr.ReadPoint(); } byte state = pr.ReadByte(); short duration = pr.ReadShort(); AbsoluteLifeMovement alm = new AbsoluteLifeMovement(type, position, state, duration, wobble, offset, fh, fhFallStart); movementList.Add(alm); break; } case 0x01: case 0x02: case 0x10: case 0x13: case 0x14: case 0x16: case 0x36: case 0x37: case 0x38: case 0x39: { Point position = pr.ReadPoint(); short fhFallStart = 0; if (type == 19 || type == 20) { fhFallStart = pr.ReadShort(); } byte state = pr.ReadByte(); short duration = pr.ReadShort(); RelativeLifeMovement rlm = new RelativeLifeMovement(type, position, state, duration, fhFallStart); movementList.Add(rlm); break; } case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x09: case 0x0A: case 0x0B: case 0x0D: case 0x18: case 0x19: case 0x31: case 0x32: case 0x33: case 0x35: { Point position = pr.ReadPoint(); short fh = pr.ReadShort(); byte state = pr.ReadByte(); short duration = pr.ReadShort(); TeleportMovement tm = new TeleportMovement(type, position, state, duration, fh); movementList.Add(tm); break; } case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F: case 0x30: case 0x34: { byte state = pr.ReadByte(); short duration = pr.ReadShort(); GroundMovement gm = new GroundMovement(type, new Point(), state, duration); movementList.Add(gm); break; } case 0x0E: { Point wobble = pr.ReadPoint(); short fhFallStart = pr.ReadShort(); byte state = pr.ReadByte(); short duration = pr.ReadShort(); WobbleMovement m = new WobbleMovement(type, wobble, fhFallStart, state, duration); movementList.Add(m); } break; case 0x0C: { byte wui = pr.ReadByte(); ChangeEquipMovement cem = new ChangeEquipMovement(type, wui); movementList.Add(cem); break; } default: ServerConsole.Warning("Unknown movement type: {0} - Data:\r\n{1}", type, pr.ToString(true)); FileLogging.Log("MovementLog.txt", String.Format("Unknown movement type: {0} - Position: {1} - Data:\r\n{2}", type, pr.Position, pr.ToString())); return(null); } } if (movements != movementList.Count) //probably hack { string packet = pr.ToString(); FileLogging.Log("MovementLog.txt", String.Format("Movement count mismatch in packet {0} Data:\r\n{1}", packet.Substring(0, 5), packet)); return(null); } return(movementList); }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; try { if (c.NpcEngine == null || c.NpcEngine.ScriptInstance == null) { if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } return; } int objectId = c.NpcEngine.ScriptInstance.ObjectId; if (objectId != -1) //objectId == -1 when npc conversation was started by the server, so players can talk to NPCs that are not on their map (with commands etc) { WzMap.Npc npc = chr.Map.GetNpc(objectId); if (npc == null) { c.NpcEngine.ScriptInstance = null; return; } } byte type = pr.ReadByte(); byte next = pr.ReadByte(); if (next == 0xFF) //End Chat { c.NpcEngine.Dispose(); return; } if (next == 0 && (type != 2)) { c.NpcEngine.ScriptInstance.State -= 1; } else { c.NpcEngine.ScriptInstance.State += 1; } bool execute = false; switch (type) { case 0: //SendOk, SendPrev, SendNext execute = true; break; case 2: //SendYesNo execute = true; c.NpcEngine.ScriptInstance.Selection = next == 0 ? 0 : 1; break; case 3: //SendAskText if (next == 0) { execute = false; } else { execute = true; string text = pr.ReadMapleString(); c.NpcEngine.ScriptInstance.InText = text; } break; case 4: //SendGetNumber //Player.GetNpcStatus().Num = pr.ReadInt(); execute = true; break; case 5: //SendSimple if (next == 0) { execute = false; } else { if (pr.Available >= 4) { c.NpcEngine.ScriptInstance.Selection = pr.ReadInt(); //This can be int as well, decided by the client } else if (pr.Available >= 1) { c.NpcEngine.ScriptInstance.Selection = pr.ReadSByte(); } execute = true; } break; case 23: //Choose Job int choice = pr.ReadInt(); break; default: string msg = "Unknown Npc chat type: " + pr.ToString(); ServerConsole.Error(msg); FileLogging.Log("NPC chat type", msg); c.NpcEngine.ScriptInstance = null; break; } if (execute) { NpcEngine engine = c.NpcEngine; if (engine == null) { if (c.Account.Character.ActionState == ActionState.NpcTalking) { c.Account.Character.EnableActions(); } return; } engine.ExecuteScriptForNpc(); } else { c.NpcEngine.ScriptInstance = null; if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } } } catch (Exception ex) { ServerConsole.Error("NpcChatMoreHandler.Handle : " + ex.ToString()); if (c.NpcEngine != null) { c.NpcEngine.ScriptInstance = null; } if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } } }
public static bool CheckAndApplySkillEffect(MapleCharacter chr, int skillId, WzCharacterSkill wzCharacterSkill, int skillLevel = -1, int numTargets = 0, int numAttacks = 0) { if (skillLevel == -1) { skillLevel = chr.GetSkillLevel(skillId); } if (wzCharacterSkill == null) { wzCharacterSkill = DataBuffer.GetCharacterSkillById(skillId); if (wzCharacterSkill == null) { return(false); } } if (wzCharacterSkill.HasFixedLevel && JobConstants.JobCanLearnSkill(skillId, chr.Job)) { skillLevel = 1; } if (chr.IsPhantom) //check stolen skill level { PhantomSystem resource = (PhantomSystem)chr.Resource; int chosenSkillIndex = resource.GetChosenSkillIndex(skillId); if (chosenSkillIndex > -1) { int impeccableMemory = PhantomSystem.GetStealSkill(chosenSkillIndex + 1); skillLevel = Math.Min(chr.GetSkillLevel(impeccableMemory), chr.GetSkillLevel(skillId)); } } if (skillLevel == 0 || (chr.HasSkillOnCooldown(skillId))) { string text = "Player tried using skill " + skillId + " while level 0 or on cooldown."; ServerConsole.Warning(text); FileLogging.Log("./LinkedSkills.txt", text); return(false); } SkillEffect effect = wzCharacterSkill.GetEffect((byte)skillLevel); if (effect == null) { return(false); } bool shadowPartner = false; if (numTargets > 0) { int attackCount = effect.AttackCount; if (chr.IsLuminous || (chr.IsBandit && chr.HasBuff(ChiefBandit.SHADOW_PARTNER)) || (chr.IsAssassin && chr.HasBuff(Hermit.SHADOW_PARTNER)) || (chr.IsNightWalker && chr.HasBuff(NightWalker3.SHADOW_PARTNER))) { attackCount *= 2; shadowPartner = true; } if (effect.MobCount < numTargets || attackCount < numAttacks) { return(false); } } int bulletConsume; if (effect.Info.TryGetValue(CharacterSkillStat.bulletConsume, out bulletConsume)) { if (shadowPartner) { bulletConsume *= 2; } if (!DealDamageHandler.HandleRangedAttackAmmoUsage(chr, bulletConsume)) { ServerConsole.Warning("Character with job: " + chr.Job + " tried using a skill with bulletCount: " + bulletConsume + " but doesn't have the bullets!"); return(false); } } if (chr.Mp < effect.MpCon) { return(false); } else { chr.AddMP(-effect.MpCon); } int hpCon; if (effect.Info.TryGetValue(CharacterSkillStat.hpCon, out hpCon)) { if (chr.Hp < hpCon) { return(false); } chr.AddHP(-hpCon); } #region Manual skill handlers and checks if (chr.IsAran && effect.Info.ContainsKey(CharacterSkillStat.aranComboCon)) { if (!AranSystem.HandleComboUsage(chr, effect.Info[CharacterSkillStat.aranComboCon])) { return(false); } } else if (chr.IsLuminous && chr.Job >= JobConstants.LUMINOUS2 && effect.Info.ContainsKey(CharacterSkillStat.gauge)) { LuminousSystem.HandleGaugeGain(chr, skillId, effect.Info[CharacterSkillStat.gauge]); } switch (skillId) { case Berserker.EVIL_EYE_OF_DOMINATION: { Buff evilEyeBuff = chr.GetBuff(Spearman.EVIL_EYE); MapleSummon evilEye = chr.GetSummon(Spearman.EVIL_EYE); if (evilEyeBuff == null || evilEye == null) { return(false); } uint timeUsed = (uint)((DateTime.UtcNow.Subtract(evilEyeBuff.StartTime)).TotalMilliseconds); uint timeRemainingMS = (uint)evilEyeBuff.Duration - timeUsed; Buff newBuff = new Buff(Spearman.EVIL_EYE, effect, timeRemainingMS, chr); if (evilEyeBuff.Stacks == Berserker.EVIL_EYE_OF_DOMINATION) { newBuff.Stacks = Spearman.EVIL_EYE; evilEye.MovementType = SummonMovementType.Follow; } else { newBuff.Stacks = Berserker.EVIL_EYE_OF_DOMINATION; evilEye.MovementType = SummonMovementType.CircleFollow; } chr.GiveBuff(newBuff); return(true); //no other actions needed } case Berserker.EVIL_EYE_SHOCK: { MapleSummon evilEye = chr.GetSummon(Spearman.EVIL_EYE); if (evilEye == null) { return(false); } List <MapleMonster> mobs = chr.Map.GetMobsInRange(new BoundingBox(evilEye.Position, wzCharacterSkill.TopLeft, wzCharacterSkill.BottomRight)); if (mobs.Count > 0) { int damage = (int)((effect.Info[CharacterSkillStat.damage] / 100.0) * chr.Stats.GetDamage()); int stunProp = effect.Info[CharacterSkillStat.prop]; int stunTime = effect.Info[CharacterSkillStat.time] * 1000; int mobCounter = 0; foreach (MapleMonster mob in mobs) { mob.Damage(chr, damage); if (mob.Alive) { if (Functions.MakeChance(stunProp)) { mob.ApplyStatusEffect(skillId, MonsterBuffStat.STUN, 1, stunTime, chr); } } mobCounter++; if (mobCounter == 10) { break; } } } break; } case DarkKnight.SACRIFICE: if (!chr.RemoveSummon(Spearman.EVIL_EYE)) { return(false); } chr.CancelBuff(Spearman.EVIL_EYE); int healHpR = effect.Info[CharacterSkillStat.y]; int heal = (int)((healHpR / 100.0) * chr.Stats.MaxHp); chr.AddHP(heal); break; case LuminousBasics.SUNFIRE: case LuminousBasics.ECLIPSE: case LuminousBasics.EQUILIBRIUM2: LuminousSystem.HandleChangeDarkLight(chr, skillId); break; } #endregion #region Apply Cooldown bool skipCooldown = skillId == DarkKnight.GUNGNIRS_DESCENT && (chr.HasBuff(DarkKnight.SACRIFICE) || chr.HasBuff(DarkKnight.FINAL_PACT2)); if (!skipCooldown) { int coolTime; if (effect.Info.TryGetValue(CharacterSkillStat.cooltime, out coolTime) && coolTime > 0) { chr.AddCooldown(skillId, (uint)coolTime * 1000); //time in the wz is in seconds } } #endregion effect.ApplyEffect(chr, chr); if (wzCharacterSkill.IsBuff) { effect.ApplyBuffEffect(chr); chr.Map.BroadcastPacket(SkillEffect.Packets.ShowForeignSkillEffect(chr.Id, chr.Level, skillId, effect.Level), chr); } if (wzCharacterSkill.IsPartySkill) { if (chr.Party != null) { List <MapleCharacter> partyMembersOnSameMap = chr.Party.GetCharactersOnMap(chr.Map, chr.Id); if (partyMembersOnSameMap.Count > 0) { List <MapleCharacter> partyMembersInRange = chr.Map.GetCharactersInRange(effect.CalculateBoundingBox(chr.Position, chr.IsFacingLeft), partyMembersOnSameMap); foreach (MapleCharacter partyMember in partyMembersInRange) { effect.ApplyEffect(chr, partyMember); if (wzCharacterSkill.IsBuff) { effect.ApplyBuffEffect(partyMember); } } } } else if (wzCharacterSkill.IsGmSkill && chr.IsStaff) { var targets = chr.Map.GetCharactersInRange(effect.CalculateBoundingBox(chr.Position, chr.IsFacingLeft)); foreach (MapleCharacter target in targets.Where(x => x.Id != chr.Id)) { effect.ApplyEffect(chr, target); if (wzCharacterSkill.IsBuff) { effect.ApplyBuffEffect(target); } } } } return(true); }