mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2026-02-04 14:31:13 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cb3a5019f | ||
|
|
d5729b4e27 | ||
|
|
7f4830d50f | ||
|
|
39d319bf70 | ||
|
|
1dd94c2d37 | ||
|
|
f6934709cc | ||
|
|
1c8ff7b143 | ||
|
|
79080cc2f0 | ||
|
|
e59ab9f798 | ||
|
|
37dfad9a29 | ||
|
|
d84a4a57a8 | ||
|
|
bb14767829 |
4
.github/workflows/push.yml
vendored
4
.github/workflows/push.yml
vendored
@ -20,10 +20,10 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Tidy Modules
|
||||
- name: Prepare Necessary Runtime Files
|
||||
run: |
|
||||
go mod tidy
|
||||
go generate main.go
|
||||
go mod tidy
|
||||
|
||||
- name: Run Lint
|
||||
uses: golangci/golangci-lint-action@master
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
//go:build !windows
|
||||
|
||||
// Package console sets console's behavior on init
|
||||
package console
|
||||
package abineundo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -1,5 +1,4 @@
|
||||
// Package console sets console's behavior on init
|
||||
package console
|
||||
package abineundo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -9,7 +9,7 @@
|
||||
//
|
||||
// Place this package at the very top of top-level main.go so its init (present
|
||||
// or future) executes before other plugin packages, filling in a predictable
|
||||
// plugin priority.
|
||||
// plugin priority and setup console properties.
|
||||
//
|
||||
// Typical usage:
|
||||
//
|
||||
|
||||
@ -18,9 +18,9 @@ buildGoApplication {
|
||||
version = "1.8.0";
|
||||
pwd = ./.;
|
||||
src = ./.;
|
||||
# spec go version manually bcs
|
||||
# https://github.com/nix-community/gomod2nix/blob/30e3c3a9ec4ac8453282ca7f67fca9e1da12c3e6/builder/default.nix#L130
|
||||
# do not work
|
||||
go = pkgs.go_1_20;
|
||||
go = pkgs.go_1_24;
|
||||
preBuild = ''
|
||||
go generate main.go
|
||||
'';
|
||||
modules = ./gomod2nix.toml;
|
||||
}
|
||||
|
||||
31
flake.lock
31
flake.lock
@ -28,11 +28,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742209644,
|
||||
"narHash": "sha256-jMy1XqXqD0/tJprEbUmKilTkvbDY/C0ZGSsJJH4TNCE=",
|
||||
"lastModified": 1767019875,
|
||||
"narHash": "sha256-NodN+lhWTD59b44Q2bPjE1edINfjfRkQYdZsrxifCeU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "8f3534eb8f6c5c3fce799376dc3b91bae6b11884",
|
||||
"rev": "49662a44272806ff785df2990a420edaaca15db4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -43,11 +43,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1745391562,
|
||||
"narHash": "sha256-sPwcCYuiEopaafePqlG826tBhctuJsLx/mhKKM5Fmjo=",
|
||||
"lastModified": 1769461804,
|
||||
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8a2f738d9d1f1d986b5a4cd2fd2061a7127237d7",
|
||||
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -57,28 +57,11 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-with-go_1_20": {
|
||||
"locked": {
|
||||
"lastModified": 1710843028,
|
||||
"narHash": "sha256-CMbK45c4nSkGvayiEHFkGFH+doGPbgo3AWfecd2t1Fk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "33c51330782cb486764eb598d5907b43dc87b4c2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "33c51330782cb486764eb598d5907b43dc87b4c2",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"gomod2nix": "gomod2nix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-with-go_1_20": "nixpkgs-with-go_1_20"
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
||||
109
flake.nix
109
flake.nix
@ -1,7 +1,6 @@
|
||||
{
|
||||
description = "基于 ZeroBot 的 OneBot 插件";
|
||||
|
||||
inputs.nixpkgs-with-go_1_20.url = "github:NixOS/nixpkgs/33c51330782cb486764eb598d5907b43dc87b4c2";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
inputs.gomod2nix.url = "github:nix-community/gomod2nix";
|
||||
@ -11,53 +10,85 @@
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
nixpkgs-with-go_1_20,
|
||||
flake-utils,
|
||||
gomod2nix,
|
||||
...
|
||||
} @ inputs: let
|
||||
allSystems = flake-utils.lib.allSystems;
|
||||
in (
|
||||
flake-utils.lib.eachSystem allSystems
|
||||
(system: let
|
||||
old-nixpkgs = nixpkgs-with-go_1_20.legacyPackages.${system};
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
}: (flake-utils.lib.eachDefaultSystem (
|
||||
system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
|
||||
overlays = [
|
||||
(_: _: {
|
||||
go_1_20 = old-nixpkgs.go_1_20;
|
||||
})
|
||||
callPackage = pkgs.callPackage;
|
||||
# Simple test check added to nix flake check
|
||||
go-test = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "go-test";
|
||||
dontBuild = true;
|
||||
src = ./.;
|
||||
doCheck = true;
|
||||
nativeBuildInputs = with pkgs; [
|
||||
go
|
||||
writableTmpDirAsHomeHook
|
||||
];
|
||||
checkPhase = ''
|
||||
go test -v ./...
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir "$out"
|
||||
'';
|
||||
};
|
||||
|
||||
# The current default sdk for macOS fails to compile go projects, so we use a newer one for now.
|
||||
# This has no effect on other platforms.
|
||||
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
|
||||
in {
|
||||
# doCheck will fail at write files
|
||||
packages = rec {
|
||||
ZeroBot-Plugin = (callPackage ./. (inputs
|
||||
// {
|
||||
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
|
||||
}))
|
||||
.overrideAttrs (_: {doCheck = false;});
|
||||
|
||||
default = ZeroBot-Plugin;
|
||||
|
||||
docker_builder = pkgs.dockerTools.buildLayeredImage {
|
||||
name = "ZeroBot-Plugin";
|
||||
tag = "latest";
|
||||
contents = [
|
||||
self.packages.${system}.ZeroBot-Plugin
|
||||
pkgs.cacert
|
||||
];
|
||||
# Simple lint check added to nix flake check
|
||||
go-lint = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "go-lint";
|
||||
dontBuild = true;
|
||||
src = ./.;
|
||||
doCheck = true;
|
||||
nativeBuildInputs = with pkgs; [
|
||||
golangci-lint
|
||||
go
|
||||
writableTmpDirAsHomeHook
|
||||
];
|
||||
checkPhase = ''
|
||||
golangci-lint run
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir "$out"
|
||||
'';
|
||||
};
|
||||
# doCheck will fail at download files
|
||||
ZeroBot-Plugin = (callPackage ./. {
|
||||
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
|
||||
}).overrideAttrs (_: {doCheck = false;});
|
||||
# Build container layered image, useful overtime to save storage on duplicated layers
|
||||
containerImage = pkgs.dockerTools.buildLayeredImage {
|
||||
name = "ZeroBot-Plugin";
|
||||
tag = "latest";
|
||||
created = "now";
|
||||
contents = [
|
||||
pkgs.cacert
|
||||
pkgs.openssl
|
||||
];
|
||||
config = {
|
||||
Cmd = ["${ZeroBot-Plugin}/bin/ZeroBot-Plugin"];
|
||||
};
|
||||
};
|
||||
in {
|
||||
inherit containerImage;
|
||||
checks = {
|
||||
inherit go-test go-lint;
|
||||
};
|
||||
packages.default = ZeroBot-Plugin;
|
||||
devShells.default = callPackage ./shell.nix {
|
||||
inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix;
|
||||
};
|
||||
# Custom application to build and load container image into the docker daemon
|
||||
# For now docker is a requirement
|
||||
apps.build-and-load = {
|
||||
type = "app";
|
||||
program = "${pkgs.writeShellScriptBin "build-and-load" ''
|
||||
nix build .#containerImage.${system}
|
||||
docker load < result
|
||||
echo "Container image loaded"
|
||||
''}/bin/build-and-load";
|
||||
};
|
||||
formatter = pkgs.alejandra;
|
||||
})
|
||||
);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
7
go.mod
7
go.mod
@ -12,7 +12,7 @@ require (
|
||||
github.com/FloatTech/sqlite v1.7.2
|
||||
github.com/FloatTech/ttl v0.0.0-20250224045156-012b1463287d
|
||||
github.com/FloatTech/zbpctrl v1.7.1
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260117132036-29f021ceb949
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260131170726-494cb1776a47
|
||||
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7
|
||||
github.com/RomiChan/websocket v1.4.3-0.20251002072000-d3eb41798438
|
||||
github.com/Tnze/go-mc v1.20.2
|
||||
@ -24,15 +24,17 @@ require (
|
||||
github.com/fumiama/cron v1.3.0
|
||||
github.com/fumiama/deepinfra v0.0.0-20251221163610-e98ee3ba437a
|
||||
github.com/fumiama/go-base16384 v1.7.1
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260117094018-cd93ccfd6e04
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260128132028-05e6b4809f0a
|
||||
github.com/fumiama/go-registry v0.2.7
|
||||
github.com/fumiama/gotracemoe v0.0.3
|
||||
github.com/fumiama/imgsz v0.0.4
|
||||
github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565
|
||||
github.com/fumiama/slowdo v0.0.0-20241001074058-27c4fe5259a4
|
||||
github.com/fumiama/terasu v1.0.2
|
||||
github.com/fumiama/unibase2n v0.0.0-20240530074540-ec743fd5a6d6
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/guohuiyuan/music-lib v1.0.2-0.20260121020416-53f6cb24629d
|
||||
github.com/jinzhu/gorm v1.9.16
|
||||
github.com/jozsefsallai/gophersauce v1.0.1
|
||||
github.com/kanrichan/resvg-go v0.0.2-0.20231001163256-63db194ca9f5
|
||||
@ -65,7 +67,6 @@ require (
|
||||
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect
|
||||
github.com/fumiama/go-simple-protobuf v0.2.0 // indirect
|
||||
github.com/fumiama/gofastTEA v0.1.3 // indirect
|
||||
github.com/fumiama/imgsz v0.0.4 // indirect
|
||||
github.com/fumiama/orbyte v0.0.0-20251002065953-3bb358367eb5 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
|
||||
10
go.sum
10
go.sum
@ -16,8 +16,8 @@ github.com/FloatTech/ttl v0.0.0-20250224045156-012b1463287d h1:mUQ/c3wXKsUGa4Sg9
|
||||
github.com/FloatTech/ttl v0.0.0-20250224045156-012b1463287d/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs=
|
||||
github.com/FloatTech/zbpctrl v1.7.1 h1:0yPEmCForhyMbnhTckmjDUFFDZgQp1RjO2bVF4ZVqOs=
|
||||
github.com/FloatTech/zbpctrl v1.7.1/go.mod h1:xmM4dSwHA02Gei3ogCRiG+RTrw/7Z69PfrN5NYf8BPE=
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260117132036-29f021ceb949 h1:1AEUIu4up84J4VqrENGyzUuYEIaQ5xYNDwIm00voL5c=
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260117132036-29f021ceb949/go.mod h1:uX5JHIADt9/vSIriLZTRwkeVvOVwxOGiDyS5O1lTPGE=
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260131170726-494cb1776a47 h1:slMr6r4XDKnYCFmWhcHA02O3MTAUnU8p2gEe843JyQA=
|
||||
github.com/FloatTech/zbputils v1.7.2-0.20260131170726-494cb1776a47/go.mod h1:W2kaR/A5oUtEb7DnveXCc0T374VjI+f3KmOWH9FE5vU=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
@ -67,8 +67,8 @@ github.com/fumiama/deepinfra v0.0.0-20251221163610-e98ee3ba437a h1:a0+2vaXajfxsN
|
||||
github.com/fumiama/deepinfra v0.0.0-20251221163610-e98ee3ba437a/go.mod h1:uqsWK/GM9OvKV0pXZOQB63rWugBbiXInY8E1JoRKhkg=
|
||||
github.com/fumiama/go-base16384 v1.7.1 h1:1P1x6FWRvd7PtbH4idDAGWAjKKcVxggxlROYKRXbw58=
|
||||
github.com/fumiama/go-base16384 v1.7.1/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260117094018-cd93ccfd6e04 h1:TAvkyECK+lSVh+AnVSPNfCmeCiYiJCd+z9QQwfjHSuw=
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260117094018-cd93ccfd6e04/go.mod h1:rTrS23rvTYuZcSngENJTvcBFTz1nGsImSv+bW7yfhqs=
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260128132028-05e6b4809f0a h1:8GYo5nctK2si5WDNX0WmZTxY7TWXRjAOBu5pjK7GDW0=
|
||||
github.com/fumiama/go-onebot-agent v0.0.0-20260128132028-05e6b4809f0a/go.mod h1:rTrS23rvTYuZcSngENJTvcBFTz1nGsImSv+bW7yfhqs=
|
||||
github.com/fumiama/go-registry v0.2.7 h1:tLEqgEpsiybQMqBv0dLHm5leia/z1DhajMupwnOHeNs=
|
||||
github.com/fumiama/go-registry v0.2.7/go.mod h1:m+wp5fF8dYgVoFkBPZl+vlK90loymaJE0JCtocVQLEs=
|
||||
github.com/fumiama/go-simple-protobuf v0.2.0 h1:ACyN1MAlu7pDR3EszWgzUeNP+IRsSHwH6V9JCJA5R5o=
|
||||
@ -117,6 +117,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopxl/beep/v2 v2.1.1 h1:6FYIYMm2qPAdWkjX+7xwKrViS1x0Po5kDMdRkq8NVbU=
|
||||
github.com/gopxl/beep/v2 v2.1.1/go.mod h1:ZAm9TGQ9lvpoiFLd4zf5B1IuyxZhgRACMId1XJbaW0E=
|
||||
github.com/guohuiyuan/music-lib v1.0.2-0.20260121020416-53f6cb24629d h1:6Cw52c4JaYvq55yAa9ZgUQeBL6b3ZWErQqkbeMZiAYw=
|
||||
github.com/guohuiyuan/music-lib v1.0.2-0.20260121020416-53f6cb24629d/go.mod h1:D/6kQDwhQFDNZEMjN8y760DQSVYpOGlQXrYzhKz0rCQ=
|
||||
github.com/jfreymuth/oggvorbis v1.0.5 h1:u+Ck+R0eLSRhgq8WTmffYnrVtSztJcYrl588DM4e3kQ=
|
||||
github.com/jfreymuth/oggvorbis v1.0.5/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII=
|
||||
github.com/jfreymuth/vorbis v1.0.2 h1:m1xH6+ZI4thH927pgKD8JOH4eaGRm18rEE9/0WKjvNE=
|
||||
|
||||
@ -29,8 +29,8 @@ schema = 3
|
||||
version = "v1.7.1"
|
||||
hash = "sha256-wkeiaUTpPVbpH7fcXeoLtG+aGIMJbvoc/9sbi2IXK0I="
|
||||
[mod."github.com/FloatTech/zbputils"]
|
||||
version = "v1.7.2-0.20260117125851-7d47971e44a2"
|
||||
hash = "sha256-uRNSP1/oLyOoxLi+QApOalEqlySrK6J1ic46ue4f6dg="
|
||||
version = "v1.7.2-0.20260131170726-494cb1776a47"
|
||||
hash = "sha256-KLhPEHoJiq2qVkK+7OVy7Wc2wpCFEJOqa/0zZGQ8TnM="
|
||||
[mod."github.com/PuerkitoBio/goquery"]
|
||||
version = "v1.8.0"
|
||||
hash = "sha256-I3QaPWATvBOL/F26fIiYWKS13yBUYo+9o3tcsGIu8tY="
|
||||
@ -92,8 +92,8 @@ schema = 3
|
||||
version = "v1.7.1"
|
||||
hash = "sha256-Fd1QaeYx+3q4C3XQXlPFnDmKPsoZH6837fN/7rn8i9s="
|
||||
[mod."github.com/fumiama/go-onebot-agent"]
|
||||
version = "v0.0.0-20260117094018-cd93ccfd6e04"
|
||||
hash = "sha256-V4Lpzn+KC1SXblNv9GnVfKd0femTaqty7wqFXuD+Roo="
|
||||
version = "v0.0.0-20260128132028-05e6b4809f0a"
|
||||
hash = "sha256-ratY7o52v0KuxgZC4wqHNXdgGXzliEecs8egE3SBLeo="
|
||||
[mod."github.com/fumiama/go-registry"]
|
||||
version = "v0.2.7"
|
||||
hash = "sha256-Rjl+z0Hlp2LMi8+pnFe5HrxctyHMi7UPiK33g/OgLdA="
|
||||
@ -142,6 +142,9 @@ schema = 3
|
||||
[mod."github.com/gopxl/beep/v2"]
|
||||
version = "v2.1.1"
|
||||
hash = "sha256-JLCUJCG+VvNlVF296JWIOUvvUFHlqEAJvZfw853qwwU="
|
||||
[mod."github.com/guohuiyuan/music-lib"]
|
||||
version = "v1.0.2-0.20260121020416-53f6cb24629d"
|
||||
hash = "sha256-juVJ/nh6zA5Gu5+dRzIx8tElXLscRQYwY9vLvVKh078="
|
||||
[mod."github.com/jfreymuth/oggvorbis"]
|
||||
version = "v1.0.5"
|
||||
hash = "sha256-jphTCaPr34ZT9Id4ZZ6zU9Vnxzy6cTjCwjpQ819eGV0="
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
package banner
|
||||
|
||||
// Version ...
|
||||
var Version = "v1.10.16"
|
||||
var Version = "v1.10.18"
|
||||
|
||||
// Copyright ...
|
||||
var Copyright = "© 2020 - 2026 FloatTech"
|
||||
|
||||
// Banner ...
|
||||
var Banner = "* OneBot + ZeroBot + Golang\n" +
|
||||
"* Version " + Version + " - 2026-01-17 21:00:49 +0800 CST\n" +
|
||||
"* Version " + Version + " - 2026-02-01 01:08:19 +0800 CST\n" +
|
||||
"* Copyright " + Copyright + ". All Rights Reserved.\n" +
|
||||
"* Project: https://github.com/FloatTech/ZeroBot-Plugin"
|
||||
|
||||
3
main.go
3
main.go
@ -14,8 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/abineundo" // 设置插件优先级
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/console" // 更改控制台属性
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/abineundo" // 设置插件优先级&更改控制台属性
|
||||
"github.com/FloatTech/ZeroBot-Plugin/kanban" // 打印 banner
|
||||
|
||||
// ---------以下插件均可通过前面加 // 注释,注释后停用并不加载插件--------- //
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/RomiChan/syncx"
|
||||
"github.com/fumiama/deepinfra"
|
||||
goba "github.com/fumiama/go-onebot-agent"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -52,7 +53,8 @@ func init() {
|
||||
logrus.Warnln("ERROR: cannot get stor")
|
||||
return false
|
||||
}
|
||||
if _, ok := ctx.State[zero.StateKeyPrefixKeep+"_chat_ag_hooked__"]; !ok && !stor.NoAgent() {
|
||||
mp := ctx.State[control.StateKeySyncxState].(*syncx.Map[string, any])
|
||||
if _, ok := mp.Load(chat.StateKeyAgentHooked); !ok && !stor.NoAgent() {
|
||||
logrus.Infoln("[aichat] skip agent for ctx has not been hooked by agent")
|
||||
return false
|
||||
}
|
||||
@ -76,6 +78,7 @@ func init() {
|
||||
stor := ctx.State[zero.StateKeyPrefixKeep+"aichatcfg_stor__"].(chat.Storage)
|
||||
temperature := stor.Temp()
|
||||
topp, maxn := chat.AC.MParams()
|
||||
mp := ctx.State[control.StateKeySyncxState].(*syncx.Map[string, any])
|
||||
|
||||
logrus.Debugln("[aichat] agent mode test: noagent", stor.NoAgent(), "hasapi", chat.AC.AgentAPI != "", "hasmodel", chat.AC.AgentModelName != "")
|
||||
if !stor.NoAgent() && chat.AC.AgentAPI != "" && chat.AC.AgentModelName != "" && chat.AC.Key != "" {
|
||||
@ -120,7 +123,7 @@ func init() {
|
||||
break
|
||||
}
|
||||
hasresp = true
|
||||
ctx.State[zero.StateKeyPrefixKeep+"_chat_ag_triggered__"] = struct{}{}
|
||||
mp.Store(chat.StateKeyAgentTriggered, struct{}{})
|
||||
for _, req := range reqs {
|
||||
if req.Action == goba.SVM { // is a fake action
|
||||
/*if hassavemem {
|
||||
|
||||
@ -1,35 +1,36 @@
|
||||
// Package music QQ音乐、网易云、酷狗、酷我、咪咕 点歌
|
||||
// Package music 整合多平台音乐点播能力
|
||||
package music
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/guohuiyuan/music-lib/kugou"
|
||||
"github.com/guohuiyuan/music-lib/kuwo"
|
||||
"github.com/guohuiyuan/music-lib/migu"
|
||||
"github.com/guohuiyuan/music-lib/netease"
|
||||
"github.com/guohuiyuan/music-lib/qq"
|
||||
"github.com/pkg/errors"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
var (
|
||||
longZhuURL = "https://www.hhlqilongzhu.cn/api/joox/juhe_music.php?msg=%v"
|
||||
)
|
||||
var platformMap = map[string]func(string) (message.Segment, error){
|
||||
"咪咕": getMiguMusic,
|
||||
"酷我": getKuwoMusic,
|
||||
"酷狗": getKugouMusic,
|
||||
"网易": getNeteaseMusic,
|
||||
"qq": getQQMusic,
|
||||
"": getKuwoMusic, // 默认点歌指向酷我
|
||||
}
|
||||
|
||||
func init() {
|
||||
control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "点歌",
|
||||
Help: "- 点歌[xxx]\n" +
|
||||
Help: "- 点歌[xxx] (默认酷我)\n" +
|
||||
"- 网易点歌[xxx]\n" +
|
||||
"- 酷我点歌[xxx]\n" +
|
||||
"- 酷狗点歌[xxx]\n" +
|
||||
@ -37,203 +38,146 @@ func init() {
|
||||
"- qq点歌[xxx]\n",
|
||||
}).OnRegex(`^(.{0,2})点歌\s?(.{1,25})$`).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
// switch 平台
|
||||
switch ctx.State["regex_matched"].([]string)[1] {
|
||||
case "咪咕":
|
||||
ctx.SendChain(migu(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "酷我":
|
||||
ctx.SendChain(kuwo(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "酷狗":
|
||||
ctx.SendChain(kugou(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "网易":
|
||||
ctx.SendChain(cloud163(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "qq":
|
||||
ctx.SendChain(qqmusic(ctx.State["regex_matched"].([]string)[2]))
|
||||
default: // 默认聚合点歌
|
||||
ctx.SendChain(longzhu(ctx.State["regex_matched"].([]string)[2]))
|
||||
matches := ctx.State["regex_matched"].([]string)
|
||||
platformPrefix := matches[1]
|
||||
keyword := matches[2]
|
||||
|
||||
processFunc, ok := platformMap[platformPrefix]
|
||||
if !ok {
|
||||
ctx.SendChain(message.Text("不支持的点播平台:", platformPrefix))
|
||||
return
|
||||
}
|
||||
|
||||
seg, err := processFunc(keyword)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("点歌失败:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(seg)
|
||||
})
|
||||
}
|
||||
|
||||
// longzhu 聚合平台
|
||||
func longzhu(keyword string) message.Segment {
|
||||
data, _ := web.GetData(fmt.Sprintf(longZhuURL, url.QueryEscape(keyword)))
|
||||
// 假设 data 是包含整个 JSON 数组的字节切片
|
||||
results := gjson.ParseBytes(data).Array()
|
||||
for _, result := range results {
|
||||
if strings.Contains(strings.ToLower(result.Get("title").String()), strings.ToLower(keyword)) {
|
||||
if musicURL := result.Get("full_track").String(); musicURL != "" {
|
||||
return message.Record(musicURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = gjson.GetBytes(data, "#.full_track").Array()
|
||||
if len(results) > 0 {
|
||||
if musicURL := results[0].String(); musicURL != "" {
|
||||
return message.Record(musicURL)
|
||||
}
|
||||
}
|
||||
|
||||
return message.Text("点歌失败, 找不到 ", keyword, " 的相关结果")
|
||||
}
|
||||
|
||||
// migu 返回咪咕音乐卡片
|
||||
func migu(keyword string) message.Segment {
|
||||
headers := http.Header{
|
||||
"Cookie": []string{"audioplayer_exist=1; audioplayer_open=0; migu_cn_cookie_id=3ad476db-f021-4bda-ab91-c485ac3d56a0; Hm_lvt_ec5a5474d9d871cb3d82b846d861979d=1671119573; Hm_lpvt_ec5a5474d9d871cb3d82b846d861979d=1671119573; WT_FPC=id=279ef92eaf314cbb8d01671116477485:lv=1671119583092:ss=1671116477485"},
|
||||
"csrf": []string{"LWKACV45JSQ"},
|
||||
"User-Agent": []string{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"},
|
||||
"Referer": []string{"http://m.music.migu.cn"},
|
||||
"proxy": []string{"false"},
|
||||
}
|
||||
// 搜索音乐信息 第一首歌
|
||||
search, _ := url.Parse("http://m.music.migu.cn/migu/remoting/scr_search_tag")
|
||||
search.RawQuery = url.Values{
|
||||
"keyword": []string{keyword},
|
||||
"type": []string{"2"},
|
||||
"pgc": []string{"1"},
|
||||
"rows": []string{"10"},
|
||||
}.Encode()
|
||||
info := gjson.ParseBytes(netGet(search.String(), headers)).Get("musics.0")
|
||||
// 返回音乐卡片
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://music.migu.cn/v3/music/song/%s", info.Get("copyrightId").String()),
|
||||
info.Get("mp3").String(),
|
||||
info.Get("songName").String(),
|
||||
).Add("content", info.Get("artist").Str).Add("image", info.Get("cover").Str).Add("subtype", "migu")
|
||||
}
|
||||
|
||||
// kuwo 返回酷我音乐卡片
|
||||
func kuwo(keyword string) message.Segment {
|
||||
headers := http.Header{
|
||||
"Cookie": []string{"Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1610284708,1610699237; _ga=GA1.2.1289529848.1591618534; kw_token=LWKACV45JSQ; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1610699468; _gid=GA1.2.1868980507.1610699238; _gat=1"},
|
||||
"csrf": []string{"LWKACV45JSQ"},
|
||||
"User-Agent": []string{"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"},
|
||||
"Referer": []string{"https://www.kuwo.cn/search/list?key="},
|
||||
}
|
||||
// 搜索音乐信息 第一首歌
|
||||
search, _ := url.Parse("https://www.kuwo.cn/api/www/search/searchMusicBykeyWord")
|
||||
search.RawQuery = url.Values{
|
||||
"key": []string{keyword},
|
||||
"pn": []string{"1"},
|
||||
"rn": []string{"1"},
|
||||
"httpsStatus": []string{"1"},
|
||||
}.Encode()
|
||||
info := gjson.ParseBytes(netGet(search.String(), headers)).Get("data.list.0")
|
||||
// 获得音乐直链
|
||||
music, _ := url.Parse("http://www.kuwo.cn/api/v1/www/music/playUrl")
|
||||
music.RawQuery = url.Values{
|
||||
"mid": []string{fmt.Sprintf("%d", info.Get("rid").Int())},
|
||||
"type": []string{"convert_url3"},
|
||||
"br": []string{"320kmp3"},
|
||||
"httpsStatus": []string{"1"},
|
||||
}.Encode()
|
||||
audio := gjson.ParseBytes(netGet(music.String(), headers))
|
||||
// 返回音乐卡片
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://www.kuwo.cn/play_detail/%d", info.Get("rid").Int()),
|
||||
audio.Get("data.url").Str,
|
||||
info.Get("name").Str,
|
||||
).Add("content", info.Get("artist").Str).Add("image", info.Get("pic").Str).Add("subtype", "kuwo")
|
||||
}
|
||||
|
||||
// kugou 返回酷狗音乐卡片
|
||||
func kugou(keyword string) message.Segment {
|
||||
stamp := time.Now().UnixNano() / 1e6
|
||||
hash := md5str(
|
||||
fmt.Sprintf(
|
||||
"NVPh5oo715z5DIWAeQlhMDsWXXQV4hwtbitrate=0callback=callback123clienttime=%dclientver=2000dfid=-inputtype=0iscorrection=1isfuzzy=0keyword=%smid=%dpage=1pagesize=30platform=WebFilterprivilege_filter=0srcappid=2919tag=emuserid=-1uuid=%dNVPh5oo715z5DIWAeQlhMDsWXXQV4hwt",
|
||||
stamp, keyword, stamp, stamp,
|
||||
),
|
||||
)
|
||||
// 搜索音乐信息 第一首歌
|
||||
h1 := http.Header{
|
||||
"User-Agent": []string{"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"},
|
||||
}
|
||||
search, _ := url.Parse("https://complexsearch.kugou.com/v2/search/song")
|
||||
search.RawQuery = url.Values{
|
||||
"callback": []string{"callback123"},
|
||||
"keyword": []string{keyword},
|
||||
"page": []string{"1"},
|
||||
"pagesize": []string{"30"},
|
||||
"bitrate": []string{"0"},
|
||||
"isfuzzy": []string{"0"},
|
||||
"tag": []string{"em"},
|
||||
"inputtype": []string{"0"},
|
||||
"platform": []string{"WebFilter"},
|
||||
"userid": []string{"-1"},
|
||||
"clientver": []string{"2000"},
|
||||
"iscorrection": []string{"1"},
|
||||
"privilege_filter": []string{"0"},
|
||||
"srcappid": []string{"2919"},
|
||||
"clienttime": []string{fmt.Sprintf("%d", stamp)},
|
||||
"mid": []string{fmt.Sprintf("%d", stamp)},
|
||||
"uuid": []string{fmt.Sprintf("%d", stamp)},
|
||||
"dfid": []string{"-"},
|
||||
"signature": []string{hash},
|
||||
}.Encode()
|
||||
res := netGet(search.String(), h1)
|
||||
info := gjson.ParseBytes(res[12 : len(res)-2]).Get("data.lists.0")
|
||||
// 获得音乐直链
|
||||
h2 := http.Header{
|
||||
"Cookie": []string{"kg_mid=d8e70a262c93d47599c6196c612d6f4f; Hm_lvt_aedee6983d4cfc62f509129360d6bb3d=1610278505,1611631363,1611722252; kg_dfid=33ZWee1kircl0jcJ1h0WF1fX; Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d=1611727348; kg_dfid_collect=d41d8cd98f00b204e9800998ecf8427e"},
|
||||
"Host": []string{"wwwapi.kugou.com"},
|
||||
"TE": []string{"Trailers"},
|
||||
"User-Agent": []string{"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"},
|
||||
}
|
||||
music := "https://wwwapi.kugou.com/yy/index.php?r=play%2Fgetdata&hash=" + info.Get("FileHash").Str + "&album_id=" + info.Get("AlbumID").Str
|
||||
audio := gjson.ParseBytes(netGet(music, h2)).Get("data")
|
||||
// 返回音乐卡片
|
||||
return message.CustomMusic(
|
||||
"https://www.kugou.com/song/#hash="+audio.Get("hash").Str+"&album_id="+audio.Get("album_id").Str,
|
||||
strings.ReplaceAll(audio.Get("play_backup_url").Str, "\\/", "/"),
|
||||
audio.Get("audio_name").Str,
|
||||
).Add("content", audio.Get("author_name").Str).Add("image", audio.Get("img").Str).Add("subtype", "kugou")
|
||||
}
|
||||
|
||||
// cloud163 返回网易云音乐卡片
|
||||
func cloud163(keyword string) (msg message.Segment) {
|
||||
requestURL := "http://music.163.com/api/search/get/web?type=1&limit=1&s=" + url.QueryEscape(keyword)
|
||||
data, err := web.GetData(requestURL)
|
||||
func getMiguMusic(keyword string) (message.Segment, error) {
|
||||
songs, err := migu.Search(keyword)
|
||||
if err != nil {
|
||||
msg = message.Text("ERROR: ", err)
|
||||
return
|
||||
return message.Segment{}, errors.Wrap(err, "咪咕音乐搜索失败")
|
||||
}
|
||||
msg = message.Music("163", gjson.ParseBytes(data).Get("result.songs.0.id").Int())
|
||||
return
|
||||
}
|
||||
if len(songs) == 0 {
|
||||
return message.Segment{}, errors.New("咪咕音乐未找到相关歌曲:" + keyword)
|
||||
}
|
||||
song := songs[0]
|
||||
|
||||
// qqmusic 返回QQ音乐卡片
|
||||
func qqmusic(keyword string) (msg message.Segment) {
|
||||
requestURL := "https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg?platform=yqq.json&key=" + url.QueryEscape(keyword)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), requestURL, "GET", "", web.RandUA(), nil)
|
||||
playURL, err := migu.GetDownloadURL(&song)
|
||||
if err != nil {
|
||||
msg = message.Text("ERROR: ", err)
|
||||
return
|
||||
return message.Segment{}, errors.Wrap(err, "获取咪咕播放链接失败")
|
||||
}
|
||||
msg = message.Music("qq", gjson.ParseBytes(data).Get("data.song.itemlist.0.id").Int())
|
||||
return
|
||||
if playURL == "" {
|
||||
return message.Segment{}, errors.New("获取咪咕播放链接失败:链接为空")
|
||||
}
|
||||
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://music.migu.cn/v3/music/song/%s", song.ID),
|
||||
playURL,
|
||||
song.Name,
|
||||
).Add("content", song.Artist).Add("image", song.Cover).Add("subtype", "migu"), nil
|
||||
}
|
||||
|
||||
// md5str 返回字符串 MD5
|
||||
func md5str(s string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(s))
|
||||
result := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
|
||||
return result
|
||||
}
|
||||
|
||||
// netGet 返回请求数据
|
||||
func netGet(url string, header http.Header) []byte {
|
||||
client := &http.Client{}
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
request.Header = header
|
||||
res, err := client.Do(request)
|
||||
func getKuwoMusic(keyword string) (message.Segment, error) {
|
||||
songs, err := kuwo.Search(keyword)
|
||||
if err != nil {
|
||||
return nil
|
||||
return message.Segment{}, errors.Wrap(err, "酷我音乐搜索失败")
|
||||
}
|
||||
defer res.Body.Close()
|
||||
result, _ := io.ReadAll(res.Body)
|
||||
return result
|
||||
if len(songs) == 0 {
|
||||
return message.Segment{}, errors.New("酷我音乐未找到相关歌曲:" + keyword)
|
||||
}
|
||||
song := songs[0]
|
||||
|
||||
playURL, err := kuwo.GetDownloadURL(&song)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "获取酷我播放链接失败")
|
||||
}
|
||||
if playURL == "" {
|
||||
return message.Segment{}, errors.New("获取酷我播放链接失败:链接为空")
|
||||
}
|
||||
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://www.kuwo.cn/play_detail/%s", song.ID),
|
||||
playURL,
|
||||
song.Name,
|
||||
).Add("content", song.Artist).Add("image", song.Cover).Add("subtype", "kuwo"), nil
|
||||
}
|
||||
|
||||
func getKugouMusic(keyword string) (message.Segment, error) {
|
||||
songs, err := kugou.Search(keyword)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "酷狗音乐搜索失败")
|
||||
}
|
||||
if len(songs) == 0 {
|
||||
return message.Segment{}, errors.New("酷狗音乐未找到相关歌曲:" + keyword)
|
||||
}
|
||||
song := songs[0]
|
||||
|
||||
playURL, err := kugou.GetDownloadURL(&song)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "获取酷狗播放链接失败")
|
||||
}
|
||||
if playURL == "" {
|
||||
return message.Segment{}, errors.New("获取酷狗播放链接失败:链接为空")
|
||||
}
|
||||
|
||||
return message.CustomMusic(
|
||||
"https://www.kugou.com/",
|
||||
playURL,
|
||||
song.Name,
|
||||
).Add("content", song.Artist).Add("image", song.Cover).Add("subtype", "kugou"), nil
|
||||
}
|
||||
|
||||
func getNeteaseMusic(keyword string) (message.Segment, error) {
|
||||
songs, err := netease.Search(keyword)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "网易云音乐搜索失败")
|
||||
}
|
||||
if len(songs) == 0 {
|
||||
return message.Segment{}, errors.New("网易云音乐未找到相关歌曲:" + keyword)
|
||||
}
|
||||
song := songs[0]
|
||||
|
||||
playURL, err := netease.GetDownloadURL(&song)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "获取网易云播放链接失败")
|
||||
}
|
||||
if playURL == "" {
|
||||
return message.Segment{}, errors.New("获取网易云播放链接失败:链接为空")
|
||||
}
|
||||
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://music.163.com/#/song?id=%s", song.ID),
|
||||
playURL,
|
||||
song.Name,
|
||||
).Add("content", song.Artist).Add("image", song.Cover).Add("subtype", "163"), nil
|
||||
}
|
||||
|
||||
func getQQMusic(keyword string) (message.Segment, error) {
|
||||
songs, err := qq.Search(keyword)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "QQ音乐搜索失败")
|
||||
}
|
||||
if len(songs) == 0 {
|
||||
return message.Segment{}, errors.New("QQ音乐未找到相关歌曲:" + keyword)
|
||||
}
|
||||
song := songs[0]
|
||||
|
||||
playURL, err := qq.GetDownloadURL(&song)
|
||||
if err != nil {
|
||||
return message.Segment{}, errors.Wrap(err, "获取QQ音乐播放链接失败")
|
||||
}
|
||||
if playURL == "" {
|
||||
return message.Segment{}, errors.New("获取QQ音乐播放链接失败:链接为空")
|
||||
}
|
||||
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://y.qq.com/n/ryqq/songDetail/%s", song.ID),
|
||||
playURL,
|
||||
song.Name,
|
||||
).Add("content", song.Artist).Add("image", song.Cover).Add("subtype", "qq"), nil
|
||||
}
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
mkGoEnv ? pkgs.mkGoEnv,
|
||||
gomod2nix ? pkgs.gomod2nix,
|
||||
}: let
|
||||
goEnv = mkGoEnv { pwd = ./.; go = pkgs.go_1_20; };
|
||||
goEnv = mkGoEnv {
|
||||
pwd = ./.;
|
||||
go = pkgs.go_1_24;
|
||||
};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"0409": {
|
||||
"identity": {
|
||||
"name": "ZeroBot-Plugin",
|
||||
"version": "1.10.16.2369"
|
||||
"version": "1.10.18.2382"
|
||||
},
|
||||
"description": "",
|
||||
"minimum-os": "vista",
|
||||
@ -36,23 +36,23 @@
|
||||
"#1": {
|
||||
"0000": {
|
||||
"fixed": {
|
||||
"file_version": "1.10.16.2369",
|
||||
"product_version": "v1.10.16",
|
||||
"timestamp": "2026-01-17T21:01:01+08:00"
|
||||
"file_version": "1.10.18.2382",
|
||||
"product_version": "v1.10.18",
|
||||
"timestamp": "2026-02-01T01:08:28+08:00"
|
||||
},
|
||||
"info": {
|
||||
"0409": {
|
||||
"Comments": "OneBot plugins based on ZeroBot",
|
||||
"CompanyName": "FloatTech",
|
||||
"FileDescription": "https://github.com/FloatTech/ZeroBot-Plugin",
|
||||
"FileVersion": "1.10.16.2369",
|
||||
"FileVersion": "1.10.18.2382",
|
||||
"InternalName": "",
|
||||
"LegalCopyright": "© 2020 - 2026 FloatTech. All Rights Reserved.",
|
||||
"LegalTrademarks": "",
|
||||
"OriginalFilename": "ZBP.EXE",
|
||||
"PrivateBuild": "",
|
||||
"ProductName": "ZeroBot-Plugin",
|
||||
"ProductVersion": "v1.10.16",
|
||||
"ProductVersion": "v1.10.18",
|
||||
"SpecialBuild": ""
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user