Пример #1
0
    private async Task ExecuteProxy(Message trigger, MessageContext ctx, AutoproxySettings autoproxySettings,
                                    ProxyMatch match, bool allowEveryone, bool allowEmbeds)
    {
        // Create reply embed
        var embeds  = new List <Embed>();
        var content = "";

        if (trigger.Type == Message.MessageType.Reply && trigger.MessageReference?.ChannelId == trigger.ChannelId)
        {
            var repliedTo = trigger.ReferencedMessage.Value;
            if (repliedTo != null)
            {
                if (trigger.Mentions.Length > 0 &&
                    repliedTo.Author.Id == trigger.Mentions[0].Id &&
                    !(trigger.Content.Contains($"<@{repliedTo.Author.Id}>") ||
                      trigger.Content.Contains($"<@!{repliedTo.Author.Id}>")))
                {
                    content = $"*<@{repliedTo.Author.Id}>*\n";
                }

                var(nickname, avatar) = await FetchReferencedMessageAuthorInfo(trigger, repliedTo);

                var embed = CreateReplyEmbed(match, trigger, repliedTo, nickname, avatar);
                if (embed != null)
                {
                    embeds.Add(embed);
                }
            }

            // TODO: have a clean error for when message can't be fetched instead of just being silent
        }

        // Send the webhook
        content += match.ProxyContent;
        if (!allowEmbeds)
        {
            content = content.BreakLinkEmbeds();
        }

        var messageChannel = await _cache.GetChannel(trigger.ChannelId);

        var rootChannel = await _cache.GetRootChannel(trigger.ChannelId);

        var threadId = messageChannel.IsThread() ? messageChannel.Id : (ulong?)null;
        var guild    = await _cache.GetGuild(trigger.GuildId.Value);

        var proxyMessage = await _webhookExecutor.ExecuteWebhook(new ProxyRequest
        {
            GuildId       = trigger.GuildId !.Value,
            ChannelId     = rootChannel.Id,
            ThreadId      = threadId,
            Name          = await FixSameName(messageChannel.Id, ctx, match.Member),
            AvatarUrl     = AvatarUtils.TryRewriteCdnUrl(match.Member.ProxyAvatar(ctx)),
            Content       = content,
            Attachments   = trigger.Attachments,
            FileSizeLimit = guild.FileSizeLimit(),
            Embeds        = embeds.ToArray(),
            Stickers      = trigger.StickerItems,
            AllowEveryone = allowEveryone
        });
Пример #2
0
        private void GetReferences()
        {
            subtitleRectTransform   = transform.GetComponent <RectTransform>();
            backgroundRectTransform = transform.parent.Find("BG").GetComponent <RectTransform>();
            try
            {
                titleText           = AvatarUtils.GetChildWithName(transform, "Title").GetComponent <Text>();
                titleTextTranslator = titleText.GetComponent <I18NText>();
            }
            catch { }

            try
            {
                subtitleText           = AvatarUtils.GetChildWithName(transform, "SubTitle").GetComponent <Text>();
                subtitleTextTranslator = subtitleText.GetComponent <I18NText>();
            }
            catch { }

            try
            {
                audioTranslator = transform.GetComponent <I18NAudioSource>();
                audioSource     = transform.GetComponent <AudioSource>();
            }
            catch { }
        }
Пример #3
0
    private async Task AvatarCommandTree(AvatarLocation location, Context ctx, PKMember target,
                                         MemberGuildSettings?guildData)
    {
        // First, see if we need to *clear*
        if (await ctx.MatchClear(location == AvatarLocation.Server
                ? "this member's server avatar"
                : "this member's avatar"))
        {
            ctx.CheckSystem().CheckOwnMember(target);
            await AvatarClear(location, ctx, target, guildData);

            return;
        }

        // Then, parse an image from the command (from various sources...)
        var avatarArg = await ctx.MatchImage();

        if (avatarArg == null)
        {
            // If we didn't get any, just show the current avatar
            await AvatarShow(location, ctx, target, guildData);

            return;
        }

        ctx.CheckSystem().CheckOwnMember(target);
        await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Value.Url);

        await UpdateAvatar(location, ctx, target, avatarArg.Value.Url);
        await PrintResponse(location, ctx, target, avatarArg.Value, guildData);
    }
Пример #4
0
    public async Task BannerImage(Context ctx, PKMember target)
    {
        ctx.CheckOwnMember(target);

        async Task ClearBannerImage()
        {
            await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = null });

            await ctx.Reply($"{Emojis.Success} Member banner image cleared.");
        }

        async Task SetBannerImage(ParsedImage img)
        {
            await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url, true);

            await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = img.Url });

            var msg = img.Source switch
            {
                AvatarSource.Url => $"{Emojis.Success} Member banner image changed to the image at the given URL.",
                AvatarSource.Attachment =>
                $"{Emojis.Success} Member banner image changed to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the banner image will stop working.",
                AvatarSource.User => throw new PKError("Cannot set a banner image to an user's avatar."),
                      _ => throw new ArgumentOutOfRangeException()
            };

            // The attachment's already right there, no need to preview it.
            var hasEmbed = img.Source != AvatarSource.Attachment;

            await(hasEmbed
                ? ctx.Reply(msg, new EmbedBuilder().Image(new Embed.EmbedImage(img.Url)).Build())
                : ctx.Reply(msg));
        }

        async Task ShowBannerImage()
        {
            if ((target.BannerImage?.Trim() ?? "").Length > 0)
            {
                var eb = new EmbedBuilder()
                         .Title($"{target.NameFor(ctx)}'s banner image")
                         .Image(new Embed.EmbedImage(target.BannerImage))
                         .Description($"To clear, use `pk;member {target.Hid} banner clear`.");
                await ctx.Reply(embed : eb.Build());
            }
            else
            {
                throw new PKSyntaxError(
                          "This member does not have a banner image set. Set one by attaching an image to this command, or by passing an image URL or @mention.");
            }
        }

        if (await ctx.MatchClear("this member's banner image"))
        {
            await ClearBannerImage();
        }
        else if (await ctx.MatchImage() is { } img)
        {
            await SetBannerImage(img);
        }
Пример #5
0
    bool HasFileReachMaxSize()
    {
        currentFile = new FileInfo(Path.GetFullPath(filePathFull));
        var fileSize = AvatarUtils.ConvertToMegabytes(currentFile.Length);
        var maxSize  = Settings.Instance.LogMaxFileSize;

        return((fileSize > maxSize) ? true : false);
    }
Пример #6
0
 public void SetupEyes(Material material, Texture texture, Texture mask, Color color)
 {
     AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                               (mat) =>
     {
         material.SetTexture(AvatarUtils._EyesTexture, texture);
         material.SetTexture(AvatarUtils._IrisMask, mask);
         material.SetColor(AvatarUtils._EyeTint, color);
         return(material);
     },
                                               "eyes");
 }
Пример #7
0
    public void SetupMouth(Material material, Texture texture, Color color)
    {
        AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                                  (mat) =>
        {
            material.SetTexture(AvatarUtils._BaseMap, texture);

            //NOTE(Brian): This isn't an error, we must also apply skin color to this mat
            material.SetColor(AvatarUtils._BaseColor, color);
            return(material);
        },
                                                  "mouth");
    }
Пример #8
0
    public void SetupDefaultMaterial(Material defaultMaterial, Color skinColor, Color hairColor)
    {
        if (assetContainer == null)
        {
            return;
        }

        if (materials == null)
        {
            materials = AvatarUtils.ReplaceMaterialsWithCopiesOf(assetContainer.transform, defaultMaterial);
        }

        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_SKIN, skinColor);
        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_HAIR, hairColor);
    }
Пример #9
0
    public void SetupEyebrows(Material material, Texture texture, Color color)
    {
        var eyebrowsMaterial = new Material(material);

        AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                                  (mat) =>
        {
            eyebrowsMaterial.SetTexture(AvatarUtils._BaseMap, texture);

            //NOTE(Brian): This isn't an error, we must also apply hair color to this mat
            eyebrowsMaterial.SetColor(AvatarUtils._BaseColor, color);

            return(eyebrowsMaterial);
        },
                                                  "eyebrows");
    }
Пример #10
0
    public void UpdateFilePath()
    {
        var outputDir = AvatarUtils.GetArg("-workspacedirectory");

        if (outputDir == null)
        {
            filePath = Application.persistentDataPath + "/logs";
        }
        else
        {
            filePath = outputDir + "/logs";
        }

        System.IO.Directory.CreateDirectory(filePath);
        filePathFull = System.IO.Path.Combine(filePath, fileName + "_" +
                                              System.DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss") + ".json");
    }
Пример #11
0
    public void SetupEyes(Material material, Texture texture, Texture mask, Color color)
    {
        if (assetContainer?.transform == null)
        {
            Debug.LogWarning("Tried to setup eyes when the asset not ready");
            return;
        }

        AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                                  (mat) =>
        {
            material.SetTexture(AvatarUtils._EyesTexture, texture);
            material.SetTexture(AvatarUtils._IrisMask, mask);
            material.SetColor(AvatarUtils._EyeTint, color);
            return(material);
        },
                                                  "eyes");
    }
        protected override void Execute(List <InputEntity> entities)
        {
            foreach (var entity in entities)
            {
                var horizontalDirection = entity.playerAvatarInput.horizontalDirection;
                var jump = entity.playerAvatarInput.jump;

                var playerEntity = gameContext.playerAvatarEntity;

                playerEntity.rigidbody.speedX = horizontalDirection * 5;

                if (jump && AvatarUtils.IsOnFloor(playerEntity, gameContext))
                {
                    playerEntity.rigidbody.speedY = -15;
                }

                entity.Destroy();
            }
        }
Пример #13
0
        internal void ShowSubtitle(MediaArchitecture newEvent, Data extraData = null)
        {
            if (!MediaIDController.MEDIAIDLOADED || !LanguageController.LANGUAGESREADY || !SoundsController.SOUNDSREADY)
            {
                Debug.Log("SUBS NOT READY");
                return;
            }

            //FETCH SUBTITLE
            SubtitleObject newSubtitle = GetSubtitleGOFromMediaID(newEvent);

            //HIDE ALL ON RESET
            if (newEvent == MediaArchitecture.Reset || newEvent == MediaArchitecture.WarningOutOfService)
            {
                HideSubtitleOfType(SubtitleType.Alarm);
                HideSubtitleOfType(SubtitleType.Costum);
                HideSubtitleOfType(SubtitleType.Workflow);
                return;
            }

            //CHECK FOR NULLS
            if (newSubtitle == null)
            {
                if (AvatarUtils.IsMediaIDAlarm(newEvent))
                {
                    HideSubtitleOfType(SubtitleType.Alarm);
#if UNITY_EDITOR
                    Debug.Log("Alarm UI null", DLogType.GUI);
#endif
                }
                if (!AvatarUtils.IsMediaIDAlarm(newEvent))
                {
                    HideSubtitleOfType(SubtitleType.Workflow);
#if UNITY_EDITOR
                    Debug.Log($"No UI for {newEvent}", DLogType.GUI);
#endif
                }
                return;
            }

            //ELSE HANDLE SUBTILE
            HandleSubtitleLogic(newSubtitle, extraData);
        }
Пример #14
0
    public void SetupEyebrows(Material material, Texture texture, Color color)
    {
        if (assetContainer?.transform == null)
        {
            Debug.LogWarning("Tried to setup eyebrows when the asset not ready");
            return;
        }

        AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                                  (mat) =>
        {
            material.SetTexture(AvatarUtils._BaseMap, texture);

            //NOTE(Brian): This isn't an error, we must also apply hair color to this mat
            material.SetColor(AvatarUtils._BaseColor, color);

            return(material);
        },
                                                  "eyebrows");
    }
Пример #15
0
    public void SetupMouth(Material material, Texture texture, Texture mask, Color color)
    {
        if (assetContainer?.transform == null)
        {
            Debug.LogWarning("Tried to setup mouth when the asset not ready");
            return;
        }

        AvatarUtils.MapSharedMaterialsRecursively(assetContainer.transform,
                                                  (mat) =>
        {
            material.SetTexture(AvatarUtils._BaseMap, texture);
            material.SetTexture(AvatarUtils._TintMask, mask);

            //NOTE(Brian): This isn't an error, we must also apply skin color to this mat
            material.SetColor(AvatarUtils._BaseColor, color);
            return(material);
        },
                                                  "mouth");
    }
Пример #16
0
    private void CheckFolderSize()
    {
        System.IO.DirectoryInfo di = new DirectoryInfo(filePath);

        FileInfo[] files = di.GetFiles().OrderBy(p => p.CreationTime).ToArray();

        long totalSize = 0;

        for (int i = 0; i < files.Length; i++)
        {
            totalSize += files[i].Length;
        }

        print(AvatarUtils.ConvertToMegabytes(totalSize) + " " + Settings.Instance.logMaxFolderSize);

        if (AvatarUtils.ConvertToMegabytes(totalSize) > Settings.Instance.logMaxFolderSize)
        {
            files[0].Delete();
        }
    }
Пример #17
0
        public void Execute()
        {
            foreach (var entity in allMovablesGroup.GetEntities())
            {
                if (entity.rigidbody.speedX != 0 || entity.rigidbody.speedY != 0)
                {
                    var newX = entity.position.x + entity.rigidbody.speedX;
                    var newY = entity.position.y + entity.rigidbody.speedY;

                    var newTilePosition = TilePositionComponent.TransformWorldPositionToTilePosition(new IntVector2(newX, newY));

                    if (TileUtils.IsSolid(newX, newY, gameContext))
                    {
                        if (entity.rigidbody.speedY > 0)
                        {
                            entity.rigidbody.speedY = 0;
                            newY = newTilePosition.ToTopLeftWorldPosition().y - 1;
                        }
                    }

                    entity.ReplacePosition(newX, newY);
                }

                if (entity.rigidbody.useGravity)
                {
                    if (!AvatarUtils.IsOnFloor(entity, gameContext))
                    {
                        entity.rigidbody.speedY++;
                        if (entity.rigidbody.speedY > 10)
                        {
                            entity.rigidbody.speedY = 10;
                        }
                    }
                    else
                    {
                        entity.rigidbody.speedY = 0;
                    }
                }
            }
        }
Пример #18
0
 public void RemoveUnusedParts()
 {
     AvatarUtils.RemoveUnusedBodyParts_Hack(assetContainer.gameObject);
 }
Пример #19
0
    public async Task NewMember(Context ctx)
    {
        if (ctx.System == null)
        {
            throw Errors.NoSystemError;
        }
        var memberName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a member name.");

        // Hard name length cap
        if (memberName.Length > Limits.MaxMemberNameLength)
        {
            throw Errors.StringTooLongError("Member name", memberName.Length, Limits.MaxMemberNameLength);
        }

        // Warn if there's already a member by this name
        var existingMember = await ctx.Repository.GetMemberByName(ctx.System.Id, memberName);

        if (existingMember != null)
        {
            var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?";
            if (!await ctx.PromptYesNo(msg, "Create"))
            {
                throw new PKError("Member creation cancelled.");
            }
        }

        await using var conn = await ctx.Database.Obtain();

        // Enforce per-system member limit
        var memberCount = await ctx.Repository.GetSystemMemberCount(ctx.System.Id);

        var memberLimit = ctx.Config.MemberLimitOverride ?? Limits.MaxMemberCount;

        if (memberCount >= memberLimit)
        {
            throw Errors.MemberLimitReachedError(memberLimit);
        }

        // Create the member
        var member = await ctx.Repository.CreateMember(ctx.System.Id, memberName, conn);

        memberCount++;

        JObject dispatchData = new JObject();

        dispatchData.Add("name", memberName);

        if (ctx.Config.MemberDefaultPrivate)
        {
            var patch = new MemberPatch().WithAllPrivacy(PrivacyLevel.Private);
            await ctx.Repository.UpdateMember(member.Id, patch, conn);

            dispatchData.Merge(patch.ToJson());
        }

        // Try to match an image attached to the message
        var       avatarArg       = ctx.Message.Attachments.FirstOrDefault();
        Exception imageMatchError = null;

        if (avatarArg != null)
        {
            try
            {
                await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Url);

                await ctx.Repository.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }, conn);

                dispatchData.Add("avatar_url", avatarArg.Url);
            }
            catch (Exception e)
            {
                imageMatchError = e;
            }
        }

        _ = _dispatch.Dispatch(member.Id, new UpdateDispatchData
        {
            Event     = DispatchEvent.CREATE_MEMBER,
            EventData = dispatchData,
        });

        // Send confirmation and space hint
        await ctx.Reply(
            $"{Emojis.Success} Member \"{memberName}\" (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#create-a-member");

        // todo: move this to ModelRepository
        if (await ctx.Database.Execute(conn => conn.QuerySingleAsync <bool>("select has_private_members(@System)",
                                                                            new { System = ctx.System.Id })) && !ctx.Config.MemberDefaultPrivate) //if has private members
        {
            await ctx.Reply(
                $"{Emojis.Warn} This member is currently **public**. To change this, use `pk;member {member.Hid} private`.");
        }
        if (avatarArg != null)
        {
            if (imageMatchError == null)
            {
                await ctx.Reply(
                    $"{Emojis.Success} Member avatar set to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the avatar will stop working.");
            }
            else
            {
                await ctx.Reply($"{Emojis.Error} Couldn't set avatar: {imageMatchError.Message}");
            }
        }
        if (memberName.Contains(" "))
        {
            await ctx.Reply(
                $"{Emojis.Note} Note that this member's name contains spaces. You will need to surround it with \"double quotes\" when using commands referring to it, or just use the member's 5-character ID (which is `{member.Hid}`).");
        }
        if (memberCount >= memberLimit)
        {
            await ctx.Reply(
                $"{Emojis.Warn} You have reached the per-system member limit ({memberLimit}). You will be unable to create additional members until existing members are deleted.");
        }
        else if (memberCount >= Limits.WarnThreshold(memberLimit))
        {
            await ctx.Reply(
                $"{Emojis.Warn} You are approaching the per-system member limit ({memberCount} / {memberLimit} members). Please review your member list for unused or duplicate members.");
        }
    }
Пример #20
0
    public async Task Avatar(Context ctx, PKSystem target)
    {
        async Task ClearIcon()
        {
            ctx.CheckOwnSystem(target);

            await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = null });

            await ctx.Reply($"{Emojis.Success} System icon cleared.");
        }

        async Task SetIcon(ParsedImage img)
        {
            ctx.CheckOwnSystem(target);

            await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url);

            await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = img.Url });

            var msg = img.Source switch
            {
                AvatarSource.User =>
                $"{Emojis.Success} System icon changed to {img.SourceUser?.Username}'s avatar!\n{Emojis.Warn} If {img.SourceUser?.Username} changes their avatar, the system icon will need to be re-set.",
                AvatarSource.Url => $"{Emojis.Success} System icon changed to the image at the given URL.",
                AvatarSource.Attachment =>
                $"{Emojis.Success} System icon changed to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the system icon will stop working.",
                _ => throw new ArgumentOutOfRangeException()
            };

            // The attachment's already right there, no need to preview it.
            var hasEmbed = img.Source != AvatarSource.Attachment;

            await(hasEmbed
                ? ctx.Reply(msg, new EmbedBuilder().Image(new Embed.EmbedImage(img.Url)).Build())
                : ctx.Reply(msg));
        }

        async Task ShowIcon()
        {
            if ((target.AvatarUrl?.Trim() ?? "").Length > 0)
            {
                var eb = new EmbedBuilder()
                         .Title("System icon")
                         .Image(new Embed.EmbedImage(target.AvatarUrl.TryGetCleanCdnUrl()));
                if (target.Id == ctx.System?.Id)
                {
                    eb.Description("To clear, use `pk;system icon clear`.");
                }
                await ctx.Reply(embed : eb.Build());
            }
            else
            {
                throw new PKSyntaxError(
                          "This system does not have an icon set. Set one by attaching an image to this command, or by passing an image URL or @mention.");
            }
        }

        if (target != null && target?.Id != ctx.System?.Id)
        {
            await ShowIcon();

            return;
        }

        if (await ctx.MatchClear("your system's icon"))
        {
            await ClearIcon();
        }
        else if (await ctx.MatchImage() is { } img)
        {
            await SetIcon(img);
        }