private OperationResponse ItemOperationDestroy(Item item, DestroyItem operation) { MethodReturnValue result = this.CheckAccess(item); if (result.IsOk) { item.Destroy(); item.Dispose(); this.RemoveItem(item); item.World.ItemCache.RemoveItem(item.Id); var eventInstance = new ItemDestroyed { ItemId = item.Id }; var eventData = new EventData((byte)EventCode.ItemDestroyed, eventInstance); this.Peer.SendEvent(eventData, new SendParameters { ChannelId = Settings.ItemEventChannel }); // no response, event is sufficient operation.OnComplete(); return(null); } return(operation.GetOperationResponse(result)); }
public UnturnedItem(Item item, DestroyItem destroyItem) { m_DestroyItem = destroyItem; Item = item; Asset = new UnturnedItemAsset((ItemAsset)Assets.find(EAssetType.ITEM, item.id)); State = new UnturnedItemState(item); }
/// <summary> /// Handles operation <see cref = "DestroyItem" />: Destroys an existing <see cref = "MmoItem" />. /// The <see cref = "MmoItem.Owner" /> must be this actor instance. /// </summary> /// <param name = "peer"> /// The client peer. /// </param> /// <param name = "request"> /// The request. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> /// <returns> /// An <see cref = "OperationResponse" /> with error code <see cref = "ReturnCode.Ok" />, <see cref = "ReturnCode.ItemNotFound" /> or <see cref = "ReturnCode.ItemAccessDenied" />. /// </returns> public override OperationResponse Handle(MmoActor actor, OperationRequest request, SendParameters sendParameters) { var operation = new DestroyItem(actor.Peer.Protocol, request); if (!operation.IsValid) { return(new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() }); } operation.OnStart(); Item item; bool actorItem = actor.TryGetItem(operation.ItemType, operation.ItemId, out item); if (actorItem == false) { IWorld world = actor.World; // search world cache just to see if item exists at all if (world.ItemCache.TryGetItem(operation.ItemType, operation.ItemId, out item) == false) { return(operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound")); } } if (actorItem) { // we are already in the item thread, invoke directly return(ItemOperationDestroy(actor, item, operation)); } // second parameter (peer) allows us to send an error event to the client (in case of an error) // error ItemAccessDenied or ItemNotFound will be returned item.Fiber.Enqueue(() => actor.ExecItemOperation(() => this.ItemOperationDestroy(actor, item, operation), sendParameters)); // operation is continued later return(null); }
void HandleDestroyItem(DestroyItem destroyItem) { ushort pos = (ushort)((destroyItem.ContainerId << 8) | destroyItem.SlotNum); // prevent drop unequipable items (in combat, for example) and non-empty bags if (Player.IsEquipmentPos(pos) || Player.IsBagPos(pos)) { InventoryResult msg = _player.CanUnequipItem(pos, false); if (msg != InventoryResult.Ok) { _player.SendEquipError(msg, _player.GetItemByPos(pos)); return; } } Item pItem = _player.GetItemByPos(destroyItem.ContainerId, destroyItem.SlotNum); if (pItem == null) { _player.SendEquipError(InventoryResult.ItemNotFound); return; } if (pItem.GetTemplate().HasFlag(ItemFlags.NoUserDestroy)) { _player.SendEquipError(InventoryResult.DropBoundItem); return; } if (destroyItem.Count != 0) { uint i_count = destroyItem.Count; _player.DestroyItemCount(pItem, ref i_count, true); } else { _player.DestroyItem(destroyItem.ContainerId, destroyItem.SlotNum, true); } }
public override IEnumerable <object> Run() { GuildStorageManager storage = this.Entity.Storage; OnlineGuildMember member = this.Entity.GetOnlineMember(this.Operation.PuchasedCID); if (!this.Entity.Storage.Valid || !FeatureMatrix.IsEnable("GuildStorage")) { member.SendOperationFailedDialog("GuildStorageFail_Processing"); storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid); this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] GuildStorage") { Reason = FailMessage.ReasonCode.LogicalFail }); } else if (this.Entity.Storage.Processing) { member.SendOperationFailedDialog("GuildStorageFail_Processing"); storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Processing); this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Entity.Storage.Processing") { Reason = FailMessage.ReasonCode.LogicalFail }); } else if (!this.Entity.Storage.IsEnabled) { member.SendOperationFailedDialog("GuildStorageFail_Stopped"); storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid); this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Entity.Storage.IsEnabled") { Reason = FailMessage.ReasonCode.LogicalFail }); } else if (storage.StorageCount >= storage.GuildStorageSlotsMax) { member.SendOperationFailedDialog("GuildStorageFail_Full"); storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid); this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] storage.StorageCount") { Reason = FailMessage.ReasonCode.LogicalFail }); } else { this.Entity.Storage.Processing = true; int targetSlotCount = 0; if (this.Entity.Storage.StorageCount == 0 && !FeatureMatrix.IsEnable("GuildStoargeSlotAllCash")) { storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.PurchaseSlotByGold); if (FeatureMatrix.GetInteger("GuildStorageSlotGoldPrice") > 0) { DestroyItem op = new DestroyItem("gold", FeatureMatrix.GetInteger("GuildStorageSlotGoldPrice"), GiveItem.SourceEnum.Unknown); OperationSync sync = new OperationSync() { Connection = member.PlayerConn, Operation = (Operation)op }; yield return((object)sync); if (!sync.Result || !op.Result) { this.Entity.Storage.Processing = false; storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_PurchaseSlotByGold); member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed"); this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] op.Result") { Reason = FailMessage.ReasonCode.LogicalFail }); yield break; } } targetSlotCount = this.Entity.Storage.GuildStorageSlotsFirstPurchase; } else { storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.PurchaseSlotByCash); if (!FeatureMatrix.IsEnable("GuildStoargeSlotFree")) { if (this.Operation.ProductNo == -1) { member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed"); storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid); this.Entity.Storage.Processing = false; this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Operation.ProductNo") { Reason = FailMessage.ReasonCode.LogicalFail }); yield break; } else { DirectPickUpByProductNo op = new DirectPickUpByProductNo() { ProductNoList = new List <int>() { this.Operation.ProductNo }, IsCredit = this.Operation.IsCredit }; OperationSync sync = new OperationSync() { Connection = member.CashShopConn, Operation = (Operation)op }; yield return((object)sync); if (!sync.Result || !op.Result || !op.ResultingItems.ContainsKey("guildstorage_ticket")) { storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_PurchaseSlotByCash); member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed"); this.Entity.Storage.Processing = false; this.Finished = true; yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] guildstorage_ticket") { Reason = FailMessage.ReasonCode.LogicalFail }); yield break; } } } targetSlotCount = this.Entity.Storage.GuildStorageSlotsPerPurchase; } storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Process); AddGuildStorageSlots requestOp = new AddGuildStorageSlots() { SlotCount = targetSlotCount }; requestOp.OnComplete += (Action <Operation>)(___ => this.Entity.Storage.StorageCount = requestOp.ResultSlotCount); OperationSync sync2 = new OperationSync() { Connection = this.Entity.Storage.ItemConn, Operation = (Operation)requestOp }; yield return((object)sync2); if (requestOp.Result) { storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Done); } else { storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_ProcessFail); } this.Entity.Storage.Processing = false; this.Entity.Storage.ReportExtendSlot(member.CharacterName, this.Entity.Storage.GuildStorageSlotsPerPurchase); this.Finished = true; yield return((object)new OkMessage()); } }
public override void Parse(EndianBinaryReader reader) { ushort length; ushort id; byte[] content; if (!IsConnected() || tcpClient.Available == 0) { return; } var lengthBuffer = reader.ReadBytes(2); lengthBuffer = _proxy.Decrypt(lengthBuffer); if (BitConverter.IsLittleEndian) { Array.Reverse(lengthBuffer); } length = BitConverter.ToUInt16(lengthBuffer, 0); if (!IsConnected()) { return; } content = _proxy.Decrypt(reader.ReadBytes(length)); EndianBinaryReader cachedReader = new EndianBinaryReader(EndianBitConverter.Big, new MemoryStream(content)); id = cachedReader.ReadUInt16(); Console.WriteLine($"Received: {id}"); switch (id) { case ServerVersionCheck.ID: ServerVersionCheck serverVersionCheck = new ServerVersionCheck(cachedReader); if (serverVersionCheck.compatible) { Compatible?.Invoke(this, EventArgs.Empty); Send(new ClientRequestCode()); } else { NotCompatible?.Invoke(this, EventArgs.Empty); thread.Abort(); } break; case ServerRequestCode.ID: ServerRequestCode serverRequestCode = new ServerRequestCode(cachedReader); Generator generator = new Generator(); generator.Build(serverRequestCode.code); _proxy.InitStageOne(generator.Output); break; case ServerRequestCallback.ID: Console.WriteLine("Stage two received"); ServerRequestCallback serverRequestCallback = new ServerRequestCallback(cachedReader); _proxy.InitStageTwo(serverRequestCallback.secretKey); Console.WriteLine("StageTwo initialized"); Console.WriteLine("Sending login request"); SendEncoded(new Ping()); SendEncoded(new Login(api.Account.UserID, api.Account.SID, 0, api.Account.InstanceID)); SendEncoded(new Ready()); break; case BuildingInit.ID: BuildingInit buildingInit = new BuildingInit(cachedReader); lock (api.buildingsLocker) api.Buildings.Add(new Building(buildingInit.BuildingID, buildingInit.Name, buildingInit.X, buildingInit.Y, buildingInit.AssetType)); break; case DestroyBuilding.ID: DestroyBuilding destroyBuilding = new DestroyBuilding(cachedReader); lock (api.buildingsLocker) api.Buildings.RemoveAll(building => building.BuildingID == destroyBuilding.BuildingID); break; case GateInit.ID: GateInit gateInit = new GateInit(cachedReader); api.Gates.Add(new Gate(gateInit.GateType, gateInit.X, gateInit.Y)); break; case ShipDestroyed.ID: ShipDestroyed shipDestroyed = new ShipDestroyed(cachedReader); if (shipDestroyed.UserID == api.Account.UserID) { Destroyed?.Invoke(this, EventArgs.Empty); } break; case Notify.ID: Notify notify = new Notify(cachedReader); if (notify.MessageType == "ttip_killscreen_basic_repair") { Destroyed?.Invoke(this, EventArgs.Empty); } break; case MapChanged.ID: MapChanged mapChanged = new MapChanged(cachedReader); Console.WriteLine($"Map changed to: {mapChanged.MapID} | {mapChanged.var_294}"); SendEncoded(new MapChangeConfirmation(true)); break; case HeroInit.ID: HeroInit heroInit = new HeroInit(cachedReader); api.Boxes.Clear(); api.MemorizedBoxes.Clear(); api.Ores.Clear(); api.Ships.Clear(); api.Gates.Clear(); api.Buildings.Clear(); // Movement api.Account.X = heroInit.X; api.Account.Y = heroInit.Y; // Map statistics api.Account.HP = (int)heroInit.HP; api.Account.MaxHP = (int)heroInit.MaxHP; api.Account.Shield = (int)heroInit.Shield; api.Account.MaxShield = (int)heroInit.MaxShield; api.Account.NanoHP = (int)heroInit.NanoHP; api.Account.MaxNanoHP = (int)heroInit.MaxNanoHP; api.Account.FreeCargoSpace = (int)heroInit.FreeCargoSpace; api.Account.CargoCapacity = (int)heroInit.CargoCapacity; // Ship api.Account.Shipname = heroInit.Shipname; api.Account.Speed = (int)(heroInit.Speed * 0.97); // Statistics api.Account.Cloaked = heroInit.Cloaked; api.Account.Jackpot = heroInit.Jackpot; api.Account.Premium = heroInit.Premium; api.Account.Credits = heroInit.Credits; api.Account.Honor = heroInit.Honor; api.Account.Uridium = heroInit.Uridium; api.Account.XP = heroInit.XP; api.Account.Level = (int)heroInit.Level; api.Account.Rank = (int)heroInit.Rank; // Social api.Account.ClanID = (int)heroInit.ClanID; api.Account.ClanTag = heroInit.ClanTag; api.Account.FactionID = heroInit.FactionID; HeroInited?.Invoke(this, EventArgs.Empty); api.Account.Ready = true; Task.Delay(15000).ContinueWith(_ => api.Account.JumpAllowed = true); SendEncoded(new InitPacket(1)); SendEncoded(new InitPacket(2)); break; case 24328: //CpuInitializationCommand SendEncoded(new OldStylePacket("JCPU|GET")); break; case DroneFormationUpdated.ID: DroneFormationUpdated droneFormationUpdated = new DroneFormationUpdated(cachedReader); break; case ShipUpdated.ID: ShipUpdated shipUpdated = new ShipUpdated(cachedReader); api.Account.UpdateHitpointsAndShield(shipUpdated.HP, shipUpdated.Shield, shipUpdated.NanoHP); break; case ShieldUpdated.ID: ShieldUpdated shieldUpdated = new ShieldUpdated(cachedReader); api.Account.UpdateShield(shieldUpdated.Shield, shieldUpdated.MaxShield); break; case CargoUpdated.ID: CargoUpdated cargoUpdated = new CargoUpdated(cachedReader); api.Account.FreeCargoSpace = api.Account.CargoCapacity - (int)cargoUpdated.CargoCount; break; case HitpointsUpdated.ID: HitpointsUpdated hitpointsUpdated = new HitpointsUpdated(cachedReader); api.Account.UpdateHitpoints(hitpointsUpdated.HP, hitpointsUpdated.MaxHP, hitpointsUpdated.NanoHP, hitpointsUpdated.MaxNanoHP); break; case ShipAttacked.ID: ShipAttacked shipAttacked = new ShipAttacked(cachedReader); Attacked?.Invoke(this, shipAttacked); break; case ShipInit.ID: ShipInit shipInit = new ShipInit(cachedReader); Ship newShip = new Ship(); newShip.UserID = (int)shipInit.UserID; newShip.Username = shipInit.Username; newShip.NPC = shipInit.NPC; // Movement newShip.X = shipInit.X; newShip.Y = shipInit.Y; // Ship newShip.Shipname = shipInit.Shipname; // Statistics newShip.Cloaked = shipInit.Cloaked; // Social newShip.ClanID = (int)shipInit.ClanID; newShip.ClanTag = shipInit.ClanTag; newShip.FactionID = (int)shipInit.FactionID; lock (api.shipsLocker) api.Ships.Add(newShip); break; case ShipMove.ID: ShipMove shipMove = new ShipMove(cachedReader); ShipMoving?.Invoke(this, shipMove); break; case BoxInit.ID: BoxInit boxInit = new BoxInit(cachedReader); if (boxInit.Hash.Length != 5) { Box box = new Box(boxInit.Hash, boxInit.X, boxInit.Y, boxInit.Type); lock (api.boxesLocker) lock (api.memorizedBoxesLocker) { api.Boxes.Add(box); api.MemorizedBoxes.Add(box); } } break; case DestroyItem.ID: DestroyItem item = new DestroyItem(cachedReader); lock (api.boxesLocker) lock (api.memorizedBoxesLocker) { api.Boxes.RemoveAll(box => box.Hash == item.Hash); if (item.CollectedByPlayer) { api.MemorizedBoxes.RemoveAll(box => box.Hash == item.Hash); } } lock (api.oresLocker) api.Ores.RemoveAll(ore => ore.Hash == item.Hash); break; case DestroyShip.ID: DestroyShip destroyedShip = new DestroyShip(cachedReader); lock (api.Ships) api.Ships.RemoveAll(ship => ship.UserID == destroyedShip.UserID); break; case OreInit.ID: OreInit oreInit = new OreInit(cachedReader); lock (api.oresLocker) api.Ores.Add(new Ore(oreInit.Hash, oreInit.X, oreInit.Y, oreInit.Type)); break; case 17162: if (!pingThread.IsAlive) { pingThread = new Thread(new ThreadStart(PingLoop)); pingThread.Start(); } break; case OldStylePacket.ID: OldStylePacket oldStylePacket = new OldStylePacket(cachedReader); string[] splittedMessage = oldStylePacket.Message.Split('|'); switch (splittedMessage[1]) { case OldPackets.SELECT: switch (splittedMessage[2]) { case OldPackets.CONFIG: api.Account.Config = Convert.ToInt32(splittedMessage[3]); break; } break; case OldPackets.PORTAL_JUMP: Console.WriteLine($"(Old) Map changed to: {splittedMessage[2]}"); SendEncoded(new MapChangeConfirmation(true)); break; case OldPackets.LOG_MESSAGE: switch (splittedMessage[3]) { case OldPackets.BOX_CONTENT_CREDITS: api.Account.CollectedCredits += double.Parse(splittedMessage[4]); break; case OldPackets.BOX_CONTENT_URIDIUM: api.Account.CollectedUridium += double.Parse(splittedMessage[4]); break; case OldPackets.BOX_CONTENT_EE: api.Account.CollectedEE += int.Parse(splittedMessage[4]); break; case OldPackets.BOX_CONTENT_XP: api.Account.CollectedXP += double.Parse(splittedMessage[4]); break; case OldPackets.BOX_CONTENT_HON: api.Account.CollectedHonor += double.Parse(splittedMessage[4]); break; } LogMessage?.Invoke(this, string.Join("|", splittedMessage)); break; default: Console.WriteLine("Received unsupported old style packet with message: {0}", oldStylePacket.Message); break; } break; default: Console.WriteLine("Received packet of ID {0} with total size of {1} which is not supported", id, length + 4); break; } }