Иконка ресурса

FREE QRLogo : 1.1.1 1.1.1

Нет прав для скачивания
C#:
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("QRLogo", "NINJA WORKS", "1.1.1")]
    public class QRLogo : RustPlugin
    {
        private const float ANIMATION_DURATION = 0.2f;
        private const float ANIMATION_FPS = 60f;
        private const float EASING_POWER = 3.5f;

        private const float QR_OFFSET_X_SMALL = -0.005f;
        private const float QR_OFFSET_Y_SMALL = -0.005f;
        private const float QR_OFFSET_X_EXPANDED = 0f;
        private const float QR_OFFSET_Y_EXPANDED = 0f;

        private const string SOUND_EFFECT = "assets/bundled/prefabs/fx/notice/item.select.fx.prefab";

        private const string UI_LOGO = "QRLogo_Logo";
        private const string UI_ANIM_CONTAINER = "QRLogo_AnimContainer";
        private const string UI_ANIM_PANEL = "QRLogo_AnimPanel";



        private ConfigData _config;
        private Dictionary<ulong, Timer> _animationTimers = new Dictionary<ulong, Timer>();
        private HashSet<ulong> _expandedPlayers = new HashSet<ulong>();
        private bool[,] _qrMatrix;

        private class ConfigData
        {
            public string QrUrl { get; set; }
            public float LogoAnchorX { get; set; }
            public float LogoAnchorY { get; set; }
            public float LogoSizePx { get; set; }
            public float ExpandedSizePx { get; set; }
            public bool EnableAnimation { get; set; }
            public string QrModuleColor { get; set; }
            public string QrBackgroundColor { get; set; }
        }

        protected override void LoadDefaultConfig()
        {
            _config = new ConfigData
            {
                QrUrl = "https://codefling.com",
                LogoAnchorX = 0.01f,
                LogoAnchorY = 0.98f,
                LogoSizePx = 80f,
                ExpandedSizePx = 500f,
                EnableAnimation = true,
                QrModuleColor = "0 0 0 1",
                QrBackgroundColor = "1 1 1 1"
            };
            SaveConfig();
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<ConfigData>();
                if (_config == null)
                {
                    LoadDefaultConfig();
                    return;
                }

                bool changed = false;
                if (string.IsNullOrEmpty(_config.QrModuleColor))
                {
                    _config.QrModuleColor = "0 0 0 1";
                    changed = true;
                }
                if (string.IsNullOrEmpty(_config.QrBackgroundColor))
                {
                    _config.QrBackgroundColor = "1 1 1 1";
                    changed = true;
                }
                if (changed)
                    SaveConfig();
            }
            catch
            {
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig() => Config.WriteObject(_config);

        private void OnServerInitialized()
        {
            _qrMatrix = QRCodeGen.Generate(EncodeUrl(_config.QrUrl));

            foreach (var player in BasePlayer.activePlayerList)
            {
                DestroyAllUI(player);
                ShowLogoUI(player);
            }
        }

        private void Unload()
        {
            foreach (var t in _animationTimers.Values)
                t?.Destroy();
            _animationTimers.Clear();
            _expandedPlayers.Clear();

            foreach (var player in BasePlayer.activePlayerList)
                DestroyAllUI(player);

            QRCodeGen.EXP = null;
            QRCodeGen.LOG = null;
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null) return;

            CleanupPlayer(player.userID);

            timer.Once(1f, () =>
            {
                if (player == null || !player.IsConnected) return;
                DestroyAllUI(player);
                ShowLogoUI(player);
            });
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (player == null) return;
            CleanupPlayer(player.userID);
        }

        [ConsoleCommand("qrlogo.expand")]
        private void CmdExpand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            if (_expandedPlayers.Contains(player.userID)) return;
            if (_animationTimers.ContainsKey(player.userID)) return;

            StartExpandAnimation(player);
        }

        [ConsoleCommand("qrlogo.collapse")]
        private void CmdCollapse(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            if (!_expandedPlayers.Contains(player.userID)) return;

            StartCollapseAnimation(player);
        }

        private void DestroyAllUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, UI_LOGO);
            CuiHelper.DestroyUi(player, UI_ANIM_CONTAINER);
        }

        private void ShowLogoUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, UI_LOGO);

            float size = _config.LogoSizePx;
            var container = new CuiElementContainer();

            container.Add(new CuiPanel
            {
                Image = { Color = _config.QrBackgroundColor },
                RectTransform = {
                    AnchorMin = $"{_config.LogoAnchorX} {_config.LogoAnchorY}",
                    AnchorMax = $"{_config.LogoAnchorX} {_config.LogoAnchorY}",
                    OffsetMin = $"0 {-size}",
                    OffsetMax = $"{size} 0"
                }
            }, "Hud", UI_LOGO);

            DrawQR(container, _qrMatrix, UI_LOGO, QR_OFFSET_X_SMALL, QR_OFFSET_Y_SMALL);

            container.Add(new CuiButton
            {
                Button = { Command = "qrlogo.expand", Color = "0 0 0 0" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "" }
            }, UI_LOGO);

            CuiHelper.AddUi(player, container);
        }

        private void ShowExpandedUI(BasePlayer player, float progress)
        {
            CuiHelper.DestroyUi(player, UI_ANIM_CONTAINER);

            float logoSize = _config.LogoSizePx;
            float expandedSize = _config.ExpandedSizePx;
            float halfExpanded = expandedSize / 2f;

            float currentAnchorX = Mathf.Lerp(_config.LogoAnchorX, 0.5f, progress);
            float currentAnchorY = Mathf.Lerp(_config.LogoAnchorY, 0.5f, progress);

            float startOffsetMinX = 0f;
            float startOffsetMinY = -logoSize;
            float startOffsetMaxX = logoSize;
            float startOffsetMaxY = 0f;

            float endOffsetMinX = -halfExpanded;
            float endOffsetMinY = -halfExpanded;
            float endOffsetMaxX = halfExpanded;
            float endOffsetMaxY = halfExpanded;

            float currentOffsetMinX = Mathf.Lerp(startOffsetMinX, endOffsetMinX, progress);
            float currentOffsetMinY = Mathf.Lerp(startOffsetMinY, endOffsetMinY, progress);
            float currentOffsetMaxX = Mathf.Lerp(startOffsetMaxX, endOffsetMaxX, progress);
            float currentOffsetMaxY = Mathf.Lerp(startOffsetMaxY, endOffsetMaxY, progress);

            float currentQrOffsetX = Mathf.Lerp(QR_OFFSET_X_SMALL, QR_OFFSET_X_EXPANDED, progress);
            float currentQrOffsetY = Mathf.Lerp(QR_OFFSET_Y_SMALL, QR_OFFSET_Y_EXPANDED, progress);

            var container = new CuiElementContainer();

            container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                CursorEnabled = true
            }, "Hud", UI_ANIM_CONTAINER);

            container.Add(new CuiButton
            {
                Button = { Command = "qrlogo.collapse", Color = "0 0 0 0" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "" }
            }, UI_ANIM_CONTAINER);

            container.Add(new CuiPanel
            {
                Image = { Color = _config.QrBackgroundColor },
                RectTransform = {
                    AnchorMin = $"{currentAnchorX} {currentAnchorY}",
                    AnchorMax = $"{currentAnchorX} {currentAnchorY}",
                    OffsetMin = $"{currentOffsetMinX} {currentOffsetMinY}",
                    OffsetMax = $"{currentOffsetMaxX} {currentOffsetMaxY}"
                }
            }, UI_ANIM_CONTAINER, UI_ANIM_PANEL);

            DrawQR(container, _qrMatrix, UI_ANIM_PANEL, currentQrOffsetX, currentQrOffsetY);

            container.Add(new CuiButton
            {
                Button = { Command = "qrlogo.collapse", Color = "0 0 0 0" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "" }
            }, UI_ANIM_PANEL);

            CuiHelper.AddUi(player, container);
        }

        private void StartExpandAnimation(BasePlayer player)
        {
            StopAnimation(player.userID);
            CuiHelper.DestroyUi(player, UI_LOGO);
            CuiHelper.DestroyUi(player, UI_ANIM_CONTAINER);

            _expandedPlayers.Add(player.userID);
            PlaySound(player);

            if (!_config.EnableAnimation)
            {
                ShowExpandedUI(player, 1f);
                return;
            }

            float elapsedTime = 0f;
            float stepInterval = 1f / ANIMATION_FPS;
            float startTime = Time.realtimeSinceStartup;
            bool done = false;

            ShowExpandedUI(player, 0f);

            _animationTimers[player.userID] = timer.Every(stepInterval, () =>
            {
                if (player == null || !player.IsConnected)
                {
                    CleanupPlayer(player?.userID ?? 0);
                    return;
                }

                elapsedTime = Time.realtimeSinceStartup - startTime;
                float t = Mathf.Clamp01(elapsedTime / ANIMATION_DURATION);
                float easedT = EaseOutPower(t, EASING_POWER);

                ShowExpandedUI(player, easedT);

                if (!done && t >= 1f)
                {
                    done = true;
                    StopAnimation(player.userID);
                }
            });
        }

        private void StartCollapseAnimation(BasePlayer player)
        {
            StopAnimation(player.userID);
            PlaySound(player);

            if (!_config.EnableAnimation)
            {
                _expandedPlayers.Remove(player.userID);
                CuiHelper.DestroyUi(player, UI_ANIM_CONTAINER);
                ShowLogoUI(player);
                return;
            }

            float elapsedTime = 0f;
            float stepInterval = 1f / ANIMATION_FPS;
            float startTime = Time.realtimeSinceStartup;
            bool done = false;

            _animationTimers[player.userID] = timer.Every(stepInterval, () =>
            {
                if (player == null || !player.IsConnected)
                {
                    CleanupPlayer(player?.userID ?? 0);
                    return;
                }

                elapsedTime = Time.realtimeSinceStartup - startTime;
                float t = Mathf.Clamp01(elapsedTime / ANIMATION_DURATION);
                float easedT = EaseOutPower(t, EASING_POWER);

                ShowExpandedUI(player, 1f - easedT);

                if (!done && t >= 1f)
                {
                    done = true;
                    StopAnimation(player.userID);
                    _expandedPlayers.Remove(player.userID);
                    CuiHelper.DestroyUi(player, UI_ANIM_CONTAINER);
                    ShowLogoUI(player);
                }
            });
        }

        private void StopAnimation(ulong playerId)
        {
            if (_animationTimers.TryGetValue(playerId, out var t))
            {
                t?.Destroy();
                _animationTimers.Remove(playerId);
            }
        }

        private void CleanupPlayer(ulong playerId)
        {
            StopAnimation(playerId);
            _expandedPlayers.Remove(playerId);
        }

        private void PlaySound(BasePlayer player)
        {
            var effect = new Effect(SOUND_EFFECT, player, 0, Vector3.zero, Vector3.zero);
            EffectNetwork.Send(effect, player.Connection);
        }

        private float EaseOutPower(float t, float power)
        {
            return 1f - Mathf.Pow(1f - t, power);
        }

        private void DrawQR(CuiElementContainer container, bool[,] matrix, string parent, float offsetX = 0f, float offsetY = 0f)
        {
            int qrSize = matrix.GetLength(0);
            int totalSize = qrSize + 2;
            float moduleSize = 1f / totalSize;

            for (int y = 0; y < qrSize; y++)
            {
                for (int x = 0; x < qrSize; x++)
                {
                    if (matrix[x, y])
                    {
                        float xMin = moduleSize + (x * moduleSize) + offsetX;
                        float yMin = moduleSize + ((qrSize - 1 - y) * moduleSize) + offsetY;

                        container.Add(new CuiPanel
                        {
                            Image = { Color = _config.QrModuleColor },
                            RectTransform = {
                                AnchorMin = $"{xMin} {yMin}",
                                AnchorMax = $"{xMin + moduleSize} {yMin + moduleSize}"
                            }
                        }, parent);
                    }
                }
            }
        }

        private string EncodeUrl(string url)
        {
            if (string.IsNullOrEmpty(url)) return url;

            var sb = new StringBuilder();
            byte[] bytes = Encoding.UTF8.GetBytes(url);

            foreach (byte b in bytes)
            {
                char c = (char)b;
                if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
                    (c >= '0' && c <= '9') || c == '-' || c == '_' ||
                    c == '.' || c == '~' || c == ':' || c == '/' ||
                    c == '?' || c == '&' || c == '=' || c == '#' ||
                    c == '%' || c == '+' || c == '@')
                {
                    sb.Append(c);
                }
                else
                {
                    sb.Append('%');
                    sb.Append(b.ToString("X2"));
                }
            }

            return sb.ToString();
        }

        private static class QRCodeGen
        {
            public static int[] EXP = new int[256];
            public static int[] LOG = new int[256];

            static QRCodeGen()
            {
                int v = 1;
                for (int i = 0; i < 256; i++)
                {
                    EXP[i] = v;
                    LOG[v] = i;
                    v <<= 1;
                    if (v >= 256) v ^= 0x11D;
                }
            }

            public static bool[,] Generate(string text)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(text);
                int ver = GetVersion(bytes.Length);
                byte[] data = Encode(text);
                int size = 17 + ver * 4;

                var matrix = new bool[size, size];
                var reserved = new bool[size, size];

                AddFinders(matrix, reserved, size);
                AddTiming(matrix, reserved, size);

                int[] alignPos = GetAlignPositions(ver);
                if (alignPos.Length > 0)
                    AddAlignments(matrix, reserved, alignPos, size);

                if (ver >= 7)
                    ReserveVersionArea(reserved, size);

                ReserveFormat(reserved, size);
                PlaceData(matrix, reserved, data, size);
                ApplyMask(matrix, reserved, size);
                AddFormat(matrix, size);

                if (ver >= 7)
                    AddVersionInfo(matrix, ver, size);

                return matrix;
            }

            private static byte[] Encode(string text)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(text);
                int ver = GetVersion(bytes.Length);
                int charCountBits = ver <= 9 ? 8 : 16;

                var bits = new List<bool>();

                AddBits(bits, 4, 4);
                AddBits(bits, bytes.Length, charCountBits);
                foreach (byte b in bytes) AddBits(bits, b, 8);

                int cap = GetCapacity(ver);
                int remaining = cap * 8 - bits.Count;
                AddBits(bits, 0, Math.Min(4, remaining));

                while (bits.Count % 8 != 0) bits.Add(false);

                bool tog = true;
                while (bits.Count < cap * 8)
                {
                    AddBits(bits, tog ? 236 : 17, 8);
                    tog = !tog;
                }

                byte[] result = new byte[bits.Count / 8];
                for (int i = 0; i < result.Length; i++)
                    for (int j = 0; j < 8; j++)
                        if (bits[i * 8 + j]) result[i] |= (byte)(128 >> j);

                return AddEC(result, ver);
            }

            private static void AddBits(List<bool> bits, int val, int cnt)
            {
                for (int i = cnt - 1; i >= 0; i--)
                    bits.Add(((val >> i) & 1) == 1);
            }

            private static int GetVersion(int dataLen)
            {
                if (dataLen <= 17) return 1;
                if (dataLen <= 32) return 2;
                if (dataLen <= 53) return 3;
                if (dataLen <= 78) return 4;
                if (dataLen <= 106) return 5;
                if (dataLen <= 134) return 6;
                if (dataLen <= 154) return 7;
                if (dataLen <= 192) return 8;
                if (dataLen <= 230) return 9;
                if (dataLen <= 271) return 10;
                if (dataLen <= 321) return 11;
                if (dataLen <= 367) return 12;
                if (dataLen <= 425) return 13;
                if (dataLen <= 458) return 14;
                if (dataLen <= 520) return 15;
                if (dataLen <= 586) return 16;
                if (dataLen <= 644) return 17;
                if (dataLen <= 718) return 18;
                if (dataLen <= 792) return 19;
                if (dataLen <= 858) return 20;
                return 20;
            }

            private static int GetCapacity(int ver)
            {
                int[] caps = { 0, 19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647, 721, 795, 861 };
                return ver < caps.Length ? caps[ver] : caps[caps.Length - 1];
            }

            private static int[] GetAlignPositions(int ver)
            {
                if (ver == 1) return new int[0];

                int[][] positions = {
                    null,
                    new int[0],
                    new int[] { 6, 18 },
                    new int[] { 6, 22 },
                    new int[] { 6, 26 },
                    new int[] { 6, 30 },
                    new int[] { 6, 34 },
                    new int[] { 6, 22, 38 },
                    new int[] { 6, 24, 42 },
                    new int[] { 6, 26, 46 },
                    new int[] { 6, 28, 50 },
                    new int[] { 6, 30, 54 },
                    new int[] { 6, 32, 58 },
                    new int[] { 6, 34, 62 },
                    new int[] { 6, 26, 46, 66 },
                    new int[] { 6, 26, 48, 70 },
                    new int[] { 6, 26, 50, 74 },
                    new int[] { 6, 30, 54, 78 },
                    new int[] { 6, 30, 56, 82 },
                    new int[] { 6, 30, 58, 86 },
                    new int[] { 6, 34, 62, 90 },
                };

                return ver < positions.Length ? positions[ver] : positions[positions.Length - 1];
            }

            private static byte[] AddEC(byte[] data, int ver)
            {
                int cap = GetCapacity(ver);
                byte[] padded = new byte[cap];
                Array.Copy(data, padded, Math.Min(data.Length, cap));

                int[] blockInfo = GetBlockInfo(ver);
                int numBlocks1 = blockInfo[0];
                int dataPerBlock1 = blockInfo[1];
                int numBlocks2 = blockInfo[2];
                int dataPerBlock2 = blockInfo[3];
                int ecPerBlock = blockInfo[4];

                var dataBlocks = new List<byte[]>();
                var ecBlocks = new List<byte[]>();
                int offset = 0;

                for (int i = 0; i < numBlocks1; i++)
                {
                    byte[] block = new byte[dataPerBlock1];
                    Array.Copy(padded, offset, block, 0, dataPerBlock1);
                    offset += dataPerBlock1;
                    dataBlocks.Add(block);
                    ecBlocks.Add(CalculateEC(block, ecPerBlock));
                }

                for (int i = 0; i < numBlocks2; i++)
                {
                    byte[] block = new byte[dataPerBlock2];
                    Array.Copy(padded, offset, block, 0, dataPerBlock2);
                    offset += dataPerBlock2;
                    dataBlocks.Add(block);
                    ecBlocks.Add(CalculateEC(block, ecPerBlock));
                }

                var result = new List<byte>();
                int maxDataLen = Math.Max(dataPerBlock1, dataPerBlock2);

                for (int i = 0; i < maxDataLen; i++)
                {
                    foreach (var block in dataBlocks)
                    {
                        if (i < block.Length)
                            result.Add(block[i]);
                    }
                }

                for (int i = 0; i < ecPerBlock; i++)
                {
                    foreach (var block in ecBlocks)
                    {
                        result.Add(block[i]);
                    }
                }

                return result.ToArray();
            }

            private static int[] GetBlockInfo(int ver)
            {
                int[][] info = {
                    null,
                    new[] { 1, 19, 0, 0, 7 },
                    new[] { 1, 34, 0, 0, 10 },
                    new[] { 1, 55, 0, 0, 15 },
                    new[] { 1, 80, 0, 0, 20 },
                    new[] { 1, 108, 0, 0, 26 },
                    new[] { 2, 68, 0, 0, 18 },
                    new[] { 2, 78, 0, 0, 20 },
                    new[] { 2, 97, 0, 0, 24 },
                    new[] { 2, 116, 0, 0, 30 },
                    new[] { 2, 68, 2, 69, 18 },
                    new[] { 4, 81, 0, 0, 20 },
                    new[] { 2, 92, 2, 93, 24 },
                    new[] { 4, 107, 0, 0, 26 },
                    new[] { 3, 115, 1, 116, 30 },
                    new[] { 5, 87, 1, 88, 22 },
                    new[] { 5, 98, 1, 99, 24 },
                    new[] { 1, 107, 5, 108, 28 },
                    new[] { 5, 120, 1, 121, 30 },
                    new[] { 3, 113, 4, 114, 28 },
                    new[] { 3, 107, 5, 108, 28 },
                };
                return ver < info.Length ? info[ver] : info[info.Length - 1];
            }

            private static byte[] CalculateEC(byte[] data, int ecCount)
            {
                int[] gen = GetGenerator(ecCount);
                int[] msg = new int[data.Length + ecCount];
                for (int i = 0; i < data.Length; i++) msg[i] = data[i];

                for (int i = 0; i < data.Length; i++)
                {
                    int c = msg[i];
                    if (c != 0)
                        for (int j = 0; j < gen.Length; j++)
                            msg[i + j] ^= Mul(gen[j], c);
                }

                byte[] result = new byte[ecCount];
                for (int i = 0; i < ecCount; i++)
                    result[i] = (byte)msg[data.Length + i];

                return result;
            }

            private static int[] GetGenerator(int deg)
            {
                int[] r = { 1 };
                for (int i = 0; i < deg; i++)
                {
                    int[] t = new int[r.Length + 1];
                    for (int j = 0; j < r.Length; j++)
                    {
                        t[j] ^= r[j];
                        t[j + 1] ^= Mul(r[j], EXP[i]);
                    }
                    r = t;
                }
                return r;
            }

            private static int Mul(int a, int b)
            {
                if (a == 0 || b == 0) return 0;
                return EXP[(LOG[a] + LOG[b]) % 255];
            }

            private static void AddFinders(bool[,] m, bool[,] r, int s)
            {
                foreach (int ox in new[] { 0, s - 7 })
                {
                    foreach (int oy in new[] { 0, s - 7 })
                    {
                        if (ox != 0 && oy != 0) continue;
                        for (int dy = -1; dy <= 7; dy++)
                        {
                            for (int dx = -1; dx <= 7; dx++)
                            {
                                int x = ox + dx, y = oy + dy;
                                if (x < 0 || y < 0 || x >= s || y >= s) continue;

                                bool blk = dx >= 0 && dx <= 6 && dy >= 0 && dy <= 6 &&
                                    (dx == 0 || dx == 6 || dy == 0 || dy == 6 ||
                                    (dx >= 2 && dx <= 4 && dy >= 2 && dy <= 4));

                                m[x, y] = blk;
                                r[x, y] = true;
                            }
                        }
                    }
                }
            }

            private static void AddTiming(bool[,] m, bool[,] r, int s)
            {
                for (int i = 8; i < s - 8; i++)
                {
                    bool blk = i % 2 == 0;
                    m[i, 6] = blk; m[6, i] = blk;
                    r[i, 6] = true; r[6, i] = true;
                }
            }

            private static void AddAlignments(bool[,] m, bool[,] r, int[] positions, int size)
            {
                if (positions.Length == 0) return;

                foreach (int cy in positions)
                {
                    foreach (int cx in positions)
                    {
                        if ((cx <= 8 && cy <= 8) ||
                            (cx <= 8 && cy >= size - 9) ||
                            (cx >= size - 9 && cy <= 8))
                            continue;

                        for (int dy = -2; dy <= 2; dy++)
                        {
                            for (int dx = -2; dx <= 2; dx++)
                            {
                                int x = cx + dx;
                                int y = cy + dy;
                                if (x < 0 || y < 0 || x >= size || y >= size) continue;

                                bool blk = dx == -2 || dx == 2 || dy == -2 || dy == 2 || (dx == 0 && dy == 0);
                                m[x, y] = blk;
                                r[x, y] = true;
                            }
                        }
                    }
                }
            }

            private static void ReserveFormat(bool[,] r, int s)
            {
                for (int i = 0; i < 9; i++) { r[i, 8] = true; r[8, i] = true; }
                for (int i = 0; i < 8; i++) { r[s - 1 - i, 8] = true; r[8, s - 1 - i] = true; }
                r[8, s - 8] = true;
            }

            private static void ReserveVersionArea(bool[,] r, int s)
            {
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        r[s - 11 + j, i] = true;
                        r[i, s - 11 + j] = true;
                    }
                }
            }

            private static void AddVersionInfo(bool[,] m, int ver, int s)
            {
                int[] versionBits = {
                    0, 0, 0, 0, 0, 0, 0,
                    0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D,
                    0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6
                };

                if (ver < 7 || ver >= versionBits.Length) return;

                int bits = versionBits[ver];

                for (int i = 0; i < 18; i++)
                {
                    bool bit = ((bits >> i) & 1) == 1;
                    int row = i / 3;
                    int col = i % 3;

                    m[s - 11 + col, row] = bit;
                    m[row, s - 11 + col] = bit;
                }
            }

            private static void PlaceData(bool[,] m, bool[,] r, byte[] d, int s)
            {
                int bi = 0, total = d.Length * 8;
                bool upward = true;

                for (int col = s - 1; col >= 1; col -= 2)
                {
                    if (col == 6) col = 5;

                    for (int i = 0; i < s; i++)
                    {
                        int row = upward ? (s - 1 - i) : i;

                        for (int c = 0; c < 2; c++)
                        {
                            int x = col - c;
                            int y = row;

                            if (!r[x, y] && bi < total)
                            {
                                m[x, y] = ((d[bi / 8] >> (7 - bi % 8)) & 1) == 1;
                                bi++;
                            }
                        }
                    }
                    upward = !upward;
                }
            }

            private static void ApplyMask(bool[,] m, bool[,] r, int s)
            {
                for (int y = 0; y < s; y++)
                    for (int x = 0; x < s; x++)
                        if (!r[x, y] && (x + y) % 2 == 0)
                            m[x, y] = !m[x, y];
            }

            private static void AddFormat(bool[,] m, int s)
            {
                int fmt = 0x77C4;
                int[] hp = { 0, 1, 2, 3, 4, 5, 7, 8 };
                int[] vp = { 8, 7, 5, 4, 3, 2, 1, 0 };

                for (int i = 0; i < 8; i++)
                {
                    bool b = ((fmt >> (14 - i)) & 1) == 1;
                    m[hp[i], 8] = b;
                    m[8, s - 1 - i] = b;
                }
                for (int i = 0; i < 7; i++)
                {
                    bool b = ((fmt >> (6 - i)) & 1) == 1;
                    m[8, vp[i]] = b;
                    m[s - 8 + i, 8] = b;
                }
                m[8, s - 8] = true;
            }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху