internal static void ReleaseBufferToPool(ref byte[] buffer) { if (buffer == null) { return; } lock (pool) { // Replace the smallest buffer: we want to cache big buffers int minIndex = 0; int minSize = Int32.MaxValue; for (int i = 0; i < pool.Length; i++) { CachedBuffer tmp = pool[i]; if (tmp == null || !tmp.IsAlive) { minIndex = 0; break; } else if (tmp.Size < minSize) { minIndex = i; minSize = tmp.Size; } } pool[minIndex] = new CachedBuffer(buffer); } // if no space, just drop it on the floor buffer = null; }
/// <summary> /// Syncs buffer. /// </summary> private int SyncBuffer(long idx) { // calculate the buffer position. var bufferPosition = idx - (idx % _bufferSize); // check buffer. if (_cachedBuffer == null || _cachedBuffer.Position != bufferPosition) { // not in buffer. if (!_cachedBuffers.TryGet(bufferPosition, out _cachedBuffer)) { var newBuffer = new T[_bufferSize]; var arrayIdx = (long)System.Math.Floor((double)bufferPosition / _accessorSize); var localIdx = bufferPosition % _accessorSize; var localPosition = localIdx * _accessors[(int)arrayIdx].ElementSize; _accessors[(int)arrayIdx].ReadArray(localPosition, newBuffer, 0, _bufferSize); _cachedBuffer = new CachedBuffer() { Buffer = newBuffer, IsDirty = false, Position = bufferPosition }; _cachedBuffers.Add(_cachedBuffer.Position, _cachedBuffer); } } return((int)(idx - bufferPosition)); }
public static void ProcessGameInformationRequest(WorldClient Client) { // On spawn le personnage try { Client.Character.SpawnToMap(); } catch (ArgumentException e) { } // On change le status Client.SetState(WorldState.STATE_IN_GAME); using (CachedBuffer Buffer = new CachedBuffer(Client)) { if (!Client.GetCharacter().isJoiningTaxFight) { if (Client.Character.myMap.mountPark != null) { Buffer.Append(new MapMountParkMessage(Client.Character.myMap.mountPark)); } // On envoie la position des joueurs Buffer.Append(new GameMapComplementaryInformationsMessage(Client.Character.myMap.GetActors())); } else { Client.GetCharacter().isJoiningTaxFight = false; } Buffer.Append(new GameDataOkMessage()); } }
internal static void ReleaseBufferToPool(ref byte[] buffer) { if (buffer == null) { return; } lock (Pool) { var minIndex = 0; var minSize = int.MaxValue; for (var i = 0; i < Pool.Length; i++) { var tmp = Pool[i]; if (tmp == null || !tmp.IsAlive) { minIndex = 0; break; } if (tmp.Size < minSize) { minIndex = i; minSize = tmp.Size; } } Pool[minIndex] = new CachedBuffer(buffer); } buffer = null; }
public void Teleport(Map NextMap, int NextCell) { if (this.myMap != null && NextMap.Id == this.myMap.Id) { //Sur la même map. if (NextCell == this.CellId) { return; } else { this.DestroyFromMap(); this.CellId = NextCell; this.myMap.SpawnActor(this); return; } } this.DestroyFromMap(); this.myMap = NextMap; this.Map = NextMap.Id; this.CellId = NextCell; if (this.Client != null) { if (Client.IsGameAction(GameActionTypeEnum.MAP_MOVEMENT)) { Client.EndGameAction(GameActionTypeEnum.MAP_MOVEMENT); } if (Client.IsGameAction(GameActionTypeEnum.CELL_ACTION)) { Client.EndGameAction(GameActionTypeEnum.CELL_ACTION); } this.Client.SetState(WorldState.STATE_GAME_INFORMATION); using (CachedBuffer Buffer = new CachedBuffer(this.Client)) { Buffer.Append(new GameActionMessage((int)GameActionTypeEnum.CHANGE_MAP, this.ActorId)); Buffer.Append(new MapDataMessage(this.myMap)); } } foreach (var Player in Follower.Values) { if (Player == null) { continue; } if (Player.IsOnline()) { Player.Send(new CharacterFlagMessage(this)); } else { Follower.Remove(Player.ActorId); } } }
public void BeginCachedBuffer() { if (this.Client != null) { this.myBuffer = new CachedBuffer(this.Client); this.myCached = true; } }
public void EndCachedBuffer() { if (this.myBuffer != null && this.Client != null) { this.myBuffer.Dispose(); this.myBuffer = null; this.myCached = false; } }
public NetPacket(ushort id, int size) { this = default(NetPacket); Id = id; Buffer = BufferPool.Request(size + 5); Length = size + 5; Writer.Write((ushort)(size + 5)); Writer.Write((byte)82); Writer.Write(id); }
public NetPacket(ushort id, int size) { this = new NetPacket(); this.Id = id; this.Buffer = BufferPool.Request(size + 5); this.Length = size + 5; this.Writer.Write((ushort)(size + 5)); this.Writer.Write((byte)82); this.Writer.Write(id); }
private async Task SendResponse(ImageContext imageContext, string key, DateTimeOffset lastModified, byte[] buffer, int length) { imageContext.ComprehendRequestHeaders(lastModified, length); string contentType = FormatHelpers.GetContentType(this.options.Configuration, key); switch (imageContext.GetPreconditionState()) { case ImageContext.PreconditionState.Unspecified: case ImageContext.PreconditionState.ShouldProcess: if (imageContext.IsHeadRequest()) { await imageContext.SendStatusAsync(ResponseConstants.Status200Ok, contentType); } this.logger.LogImageServed(imageContext.GetDisplayUrl(), key); if (buffer == null) { // We're pulling the buffer from the cache. This should be pooled. CachedBuffer cachedBuffer = await this.cache.GetAsync(key); await imageContext.SendAsync(contentType, cachedBuffer.Buffer, cachedBuffer.Length); BufferDataPool.Return(cachedBuffer.Buffer); } else { await imageContext.SendAsync(contentType, buffer, length); } break; case ImageContext.PreconditionState.NotModified: this.logger.LogImageNotModified(imageContext.GetDisplayUrl()); await imageContext.SendStatusAsync(ResponseConstants.Status304NotModified, contentType); break; case ImageContext.PreconditionState.PreconditionFailed: this.logger.LogImagePreconditionFailed(imageContext.GetDisplayUrl()); await imageContext.SendStatusAsync(ResponseConstants.Status412PreconditionFailed, contentType); break; default: var exception = new NotImplementedException(imageContext.GetPreconditionState().ToString()); Debug.Fail(exception.ToString()); throw exception; } }
/// <summary> /// Returns a buffer of the given size or greater. /// </summary> /// <exception cref="BufferAcquisitionException">If the buffer could /// not be taken from a pool, and the ActionOnBufferUnavailable /// is set to ThrowException, or if the specified size is greater /// than the maximum buffer size.</exception> /// <exception cref="ArgumentOutOfRangeException">If minimumSize is less than 0.</exception> public IBuffer GetBuffer(int minimumSize) { if (minimumSize < 0) { throw new ArgumentOutOfRangeException("minimumSize must be greater than or equal to 0"); } if (minimumSize > options.MaxBufferSize) { throw new BufferAcquisitionException("Requested buffer " + minimumSize + " is larger " + "than maximum buffer size " + options.MaxBufferSize); } // Work out the size of buffer to use, and where in the list to find // cached buffers int listIndex = 0; int size = options.MinBufferSize; while (size < minimumSize) { size = CalculateNextSizeBand(size); listIndex++; } // Loop in case we need to find the next size up while (true) { CachedBuffer ret = FindAvailableBuffer(listIndex, size); if (ret != null) { return(ret); } switch (options.ActionOnBufferUnavailable) { case Options.BufferUnavailableAction.ReturnUncached: return(new CachedBuffer(minimumSize, options.ClearAfterUse)); case Options.BufferUnavailableAction.ThrowException: throw new BufferAcquisitionException("No buffers available"); } // Must be "use bigger". Use an uncached buffer if we've reached the maximum size, // otherwise try the next size band if (size == options.MaxBufferSize) { return(new CachedBuffer(minimumSize, options.ClearAfterUse)); } size = CalculateNextSizeBand(size); listIndex++; } }
public static void ProcessGameCreateRequest(WorldClient Client) { Client.SetState(WorldState.STATE_GAME_INFORMATION); using (CachedBuffer Buffer = new CachedBuffer(Client)) { Buffer.Append(new GameCreateMessage()); Buffer.Append(new MapDataMessage(Client.Character.myMap)); Buffer.Append(new AccountStatsMessage(Client.Character)); } if (Client.hasFightMessage) { if (Client.Character.FightType == -1) { return; } if (Client.Character.FightType == -3) { if (Client.Character.OldPosition != null) { Client.Character.Teleport(Client.Character.OldPosition.first, Client.Character.OldPosition.second); } Client.Send(new GameLeaveMessage()); Client.SetState(WorldState.STATE_GAME_CREATE); Client.hasFightMessage = false; Client.Character.OldPosition = null; Client.Character.FightType = -1; return; } if (Client.Character.FightType == -2) { Client.Character.WarpToSavePos(); Client.Send(new GameLeaveMessage()); Client.SetState(WorldState.STATE_GAME_CREATE); Client.hasFightMessage = false; Client.Character.FightType = -1; return; } Client.Character.myMap.applyEndFightAction((int)Client.Character.FightType, Client.Character); Client.Send(new GameLeaveMessage()); Client.SetState(WorldState.STATE_GAME_CREATE); Client.hasFightMessage = false; Client.Character.FightType = -1; } }
/// <summary> /// Gets a cached buffer with a minimum size of <paramref name="minSize"/>. /// </summary> /// <remarks> /// The method returns the smallest cached buffer with a size greater than <paramref name="minSize"/> or <c>null</c> if none was found. /// </remarks> internal static byte[] GetCachedBuffer(int minSize) { if (minSize <= 0) { throw new ArgumentOutOfRangeException("minSize"); } lock (pool) { int bestIndex = -1; byte[] bestMatch = null; for (int i = 0; i < pool.Length; i++) { CachedBuffer buffer = pool[i]; if (buffer == null || buffer.Size < minSize) { continue; // This buffer is useless: either null or too small } else if (bestMatch != null && bestMatch.Length < buffer.Size) { continue; // We already have a smaller fitting buffer. } byte[] tmp = buffer.Buffer; // Get a reference to the cached byte array, check if it has already been collected. if (tmp == null) { pool[i] = null; // Already collected, we can forget it } else { bestMatch = tmp; bestIndex = i; } } if (bestIndex >= 0) { pool[bestIndex] = null; } return(bestMatch); } }
/// <summary> /// Finds an available buffer from the list, creating a new buffer /// where appropriate. /// </summary> /// <param name="listIndex">Index into the list of buffer slots</param> /// <param name="size">Size of buffer to create if necessary</param> /// <returns>An available buffer, or null if none are available in the given band.</returns> CachedBuffer FindAvailableBuffer(int listIndex, int size) { using (padlock.Lock()) { // Make sure there'll be an entry, even if it's null while (listIndex >= bufferBands.Count) { bufferBands.Add(null); } // Create a new array of buffers if necessary CachedBuffer[] buffers = bufferBands[listIndex]; if (buffers == null) { buffers = new CachedBuffer[options.MaxBuffersPerSizeBand]; bufferBands[listIndex] = buffers; } // Look through all the buffers in this band for an available one, or an unused slot for (int i = 0; i < buffers.Length; i++) { // No cached unused buffers. Create a new one. if (buffers[i] == null) { buffers[i] = new CachedBuffer(size, options.ClearAfterUse); return(buffers[i]); } if (buffers[i].Available) { buffers[i].Available = false; return(buffers[i]); } } return(null); } }
private static void ProcessCharacterCreationRequest(WorldClient Client, string Packet) { var characterInfos = Packet.Substring(2); // fake Packet if (!characterInfos.Contains('|')) { Client.Disconnect(); return; } var infos = characterInfos.Split('|'); // fake Packet if (infos.Length != 6) { Client.Disconnect(); return; } String first = (infos[0][0].ToString()).ToUpper(); var Name = first + infos[0].Substring(1).ToLower(); var Class = int.Parse(infos[1]); var Sex = int.Parse(infos[2]); var Color1 = int.Parse(infos[3]); var Color2 = int.Parse(infos[4]); var Color3 = int.Parse(infos[5]); // trop de personnage if (Client.Account.Characters.Count > (Settings.AppSettings.GetIntElement("Account.MaxPlayer") - 1)) { Client.Send(new CharacterSlotFullMessage()); return; } // fake class if (!StringHelper.isValidName(Name) || Class < (int)ClassEnum.CLASS_FECA || Class > (int)ClassEnum.CLASS_PANDAWA) { Client.Send(new CharacterCreationFailMessage()); return; } // fake sex if (Sex > 1 || Sex < 0) { Client.Send(new CharacterCreationFailMessage()); return; } // fake color if (Color1 < -1 || Color2 < -1 || Color3 < -1) { Client.Send(new CharacterCreationFailMessage()); return; } // pseudo deja pris ? if (CharacterTable.Contains(Name) || 4 > Name.Length) { Client.Send(new CharacterNameAlreadyExistMessage()); return; } var character = new Database.Models.Player() { ID = DatabaseCache.nextPlayerGuid++, Owner = Client.Account.ID, Name = Name, Level = Settings.AppSettings.GetIntElement("World.StartLevel"), Color1 = Color1, Color2 = Color2, Color3 = Color3, Look = Class * 10, Sexe = Sex, Classe = Class, EnabledChannels = "i*#$p%!?:@", Map = Settings.AppSettings.GetShortElement("World.StartMap"), CellId = Settings.AppSettings.GetIntElement("World.StartCell"), Restriction = 0, Experience = ExpFloorTable.GetFloorByLevel(Settings.AppSettings.GetIntElement("World.StartLevel")).Character, Kamas = Settings.AppSettings.GetIntElement("World.KamasStart"), CaractPoint = (Settings.AppSettings.GetIntElement("World.StartLevel") - 1) * 5, SpellPoint = Settings.AppSettings.GetIntElement("World.StartLevel") - 1, LifePer = 100, Energy = 10000, AP = (Settings.AppSettings.GetIntElement("World.StartLevel") >= 100 ? 7 : 6), MP = 3, Vitality = 0, Wisdom = 0, Strength = 0, Intell = 0, Agility = 0, Chance = 0, Alignement = 0, Honor = 0, Deshonor = 0, Stuff = "", MountID = -1, MountXPGive = 0, Title = 0, SavePos = Settings.AppSettings.GetShortElement("World.StartMap") + "," + Settings.AppSettings.GetIntElement("World.StartCell"), Account = Client.Account, }; if (!CharacterTable.Add(character)) { Client.Send(new CharacterCreationFailMessage()); return; } Client.Account.Characters.Add(character.ID, character); using (CachedBuffer Buffer = new CachedBuffer(Client)) { Buffer.Append(new CharacterCreationSuccessMessage()); Buffer.Append(new CharactersListMessage(Client.Account.Characters)); } }
public NetPacket(ushort id, int size) { Id = id; Buffer = BufferPool.Request(size); Length = size; }
public NetPacket(ushort id, int size) { this.Id = id; this.Buffer = BufferPool.Request(size); this.Length = size; }