commit 9b1d8a5b3b0edc6e722a1c0660602d5ed78346c2 Author: jack77213 Date: Sun Aug 2 15:48:08 2020 +0800 Init diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b5bdc58 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +LDFLAGS=-ldflags "" + +GOSRC = $(shell find ./extension -type f -name '*.go' -not -path "./vendor/*") +ARMASRC = $(shell find ./addons -type f -name '*') + +.PHONY: build clean + +all: clean build + +a3tg.pbo: $(ARMASRC) + armake2 pack -v addons a3tg.pbo + +liba3tg.so: $(GOSRC) + cd extension && GOARCH=386 CGO_ENABLED=1 go build $(LDFLAGS) -o ../liba3tg.so -buildmode=c-shared . + +liba3tg.dll: $(GOSRC) + cd extension && GOOS=windows GOARCH=386 CC=i686-w64-mingw32-cc CGO_ENABLED=1 go build $(LDFLAGS) -o ../liba3tg.dll -buildmode=c-shared . + +liba3tg_x64.dll: $(GOSRC) + cd extension && GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-cc CGO_ENABLED=1 go build $(LDFLAGS) -o ../liba3tg_x64.dll -buildmode=c-shared . + +build: liba3tg.so liba3tg.dll liba3tg_x64.dll a3tg.pbo + +clean: + -rm a3tg.pbo + -rm ./liba3tg.so + -rm ./liba3tg.dll + -rm ./liba3tg_x64.dll + -rm ./liba3tg.h + -rm ./liba3tg_x64.h diff --git a/addons/$PBOPREFIX$ b/addons/$PBOPREFIX$ new file mode 100644 index 0000000..d1ca4fd --- /dev/null +++ b/addons/$PBOPREFIX$ @@ -0,0 +1 @@ +x\huashui\a3tg \ No newline at end of file diff --git a/addons/config.cpp b/addons/config.cpp new file mode 100644 index 0000000..fb67b8d --- /dev/null +++ b/addons/config.cpp @@ -0,0 +1,28 @@ +class CfgPatches +{ + class a3tg + { + name = "Arma 3 Telegram Bridge"; + author = "jack77213"; + url = "https://arma.huashui.cf"; + + requiredVersion = 1.92; + requiredAddons[] = {"A3_Functions_F"}; + units[] = {}; + weapons[] = {}; + }; +}; + +class CfgFunctions +{ + class huashui + { + class a3tg + { + file = "x\huashui\a3tg"; + class a3tg { postInit=1; }; + class sendmsg {}; + }; + }; +}; + diff --git a/addons/fn_a3tg.sqf b/addons/fn_a3tg.sqf new file mode 100644 index 0000000..487b631 --- /dev/null +++ b/addons/fn_a3tg.sqf @@ -0,0 +1,33 @@ + +if (!isServer) exitWith {}; + +[] spawn { + //if (!hasInterface) exitWith {}; + if (!isServer) exitWith {}; + //if (!isDedicated) exitWith {}; + + "liba3tg" callExtension ["chat", []]; + + waitUntil {time > 0}; + + addMissionEventHandler ["ExtensionCallback", { + params ["_name", "_function", "_data"]; + if (_name isEqualTo "a3tg") then + { + (format ["[TG] %2: %3", _function, _data]) remoteExecCall ["systemChat", -2, true]; + }; + }]; + + huashui_a3tg_client = { + [] spawn { + waitUntil {time > 0}; + ["cba_events_chatMessageSent", { + params ["_message"]; + [name player, _message] remoteExecCall ["huashui_fnc_sendmsg", 2, false]; + }] call CBA_fnc_addEventHandler; + }; + }; + publicVariable "huashui_a3tg_client"; + remoteExecCall ["huashui_a3tg_client", -2, true]; + +}; diff --git a/addons/fn_sendmsg.sqf b/addons/fn_sendmsg.sqf new file mode 100644 index 0000000..5a293e0 --- /dev/null +++ b/addons/fn_sendmsg.sqf @@ -0,0 +1,4 @@ +params ["_name", "_message"]; + +"liba3tg" callExtension ["chat", [_name, _message]]; + diff --git a/extension/go.mod b/extension/go.mod new file mode 100644 index 0000000..8132b59 --- /dev/null +++ b/extension/go.mod @@ -0,0 +1,5 @@ +module gitea.hijack.moe/huashui/a3tg/extension + +go 1.13 + +require github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200729154208-fb8759e91dfc diff --git a/extension/go.sum b/extension/go.sum new file mode 100644 index 0000000..95dbe13 --- /dev/null +++ b/extension/go.sum @@ -0,0 +1,4 @@ +github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200729154208-fb8759e91dfc h1:4N4M0RFas9m30PaUYz+czoIqvmduqOW/xQ7rYXF3nNI= +github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200729154208-fb8759e91dfc/go.mod h1:lDm2E64X4OjFdBUA4hlN4mEvbSitvhJdKw7rsA8KHgI= +github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= +github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= diff --git a/extension/liba3tg.go b/extension/liba3tg.go new file mode 100644 index 0000000..79ad2bf --- /dev/null +++ b/extension/liba3tg.go @@ -0,0 +1,92 @@ +package main + +/* + #include + #include + #include + + typedef int(*callbackProc)(char const *name, char const *function, char const *data); + + static inline int bridge_cb(callbackProc cb, char const *name, char const *function, char const *data) { + return cb(name, function, data); + } + + #if __x86_64__ + static inline unsigned long long min(unsigned long long a, unsigned long long b) { return a < b ? a : b; } + #else + static inline unsigned int min(unsigned int a, unsigned int b) { return a < b ? a : b; } + #endif + +*/ +import "C" + +import ( + "fmt" + "log" + "unsafe" +) + +var cb C.callbackProc +var name = C.CString("a3tg") + +func sendToArma(user, msg string) error { + C.bridge_cb(cb, name, C.CString(user), C.CString(msg)) + return nil +} + +// RVExtensionRegisterCallback on extension load +//export RVExtensionRegisterCallback +func RVExtensionRegisterCallback(cbptr unsafe.Pointer) { + cb = C.callbackProc(cbptr) + + botInit() + go telegramBridge() + + log.Println("Calling callback function ……") + function := C.CString("registered") + defer C.free(unsafe.Pointer(function)) + C.bridge_cb(cb, name, function, function) +} + +// RVExtensionVersion on extension load +//export RVExtensionVersion +func RVExtensionVersion(output *C.char, outputsize C.size_t) { + version := C.CString("Version 0.1") + defer C.free(unsafe.Pointer(version)) + var size = C.min(C.strlen(version)+1, outputsize-1) + C.strncpy(output, version, size) +} + +// RVExtensionArgs STRING callExtension ARRAY +//export RVExtensionArgs +func RVExtensionArgs(output *C.char, outputsize C.size_t, function *C.char, argv **C.char, argc C.int) { + var offset = unsafe.Sizeof(uintptr(0)) + var out []string + for index := C.int(0); index < argc; index++ { + out = append(out, C.GoString(*argv)) + argv = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(argv)) + offset)) + } + + go handleArgs(C.GoString(function), argc, out) +} + +// RVExtension STRING callExtension STRING +//export RVExtension +func RVExtension(output *C.char, outputsize C.size_t, function *C.char) { + result := C.CString(fmt.Sprintf("Hello, %s!", C.GoString(function))) + defer C.free(unsafe.Pointer(result)) + var size = C.min(C.strlen(result)+1, outputsize-1) + C.strncpy(output, result, size) +} + +func main() {} + +func handleArgs(function string, argc C.int, argv []string) { + if function != "chat" || argc != 2 { + log.Println("argc", argc) + return + } + + sendToTelegram(argv[0], argv[1]) + //log.Println(argc, argv[0], argv[1]) +} diff --git a/extension/telegram.go b/extension/telegram.go new file mode 100644 index 0000000..c5fcf9e --- /dev/null +++ b/extension/telegram.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" +) + +var bot *tgbotapi.BotAPI +var groupID int64 +var botAPIKey string + +func botInit() { + var err error + botAPIKey = os.Getenv("TELEGRAM_APIKEY") + groupID, err = strconv.ParseInt(os.Getenv("TELEGRAM_GROUPID"), 10, 64) + if err != nil { + log.Println(err) + } + + bot, err = tgbotapi.NewBotAPI(botAPIKey) + if err != nil { + log.Println(err) + } else { + log.Printf("Bot 名称: %s", bot.Self.UserName) + } +} + +func telegramBridge() { + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + updates, err := bot.GetUpdatesChan(u) + if err != nil { + log.Println(err) + } + + for update := range updates { + if update.Message == nil { + continue + } + + log.Printf("<%s> %s", update.Message.From.UserName, update.Message.Text) + + if update.Message.IsCommand() { + //handleCommands(bot, update) + continue + } + + if update.Message.Chat.ID == groupID { + sendToArma(update.Message.From.UserName, update.Message.Text) + } + } +} + +func sendToTelegram(player, message string) { + msgText := fmt.Sprintf("[Arma3] <%s> %s\n", player, message) + log.Println(msgText) + msg := tgbotapi.NewMessage(groupID, msgText) + bot.Send(msg) +}