From 5b2886d094632c76fd15cf2c6e1b9d1b98270f3f Mon Sep 17 00:00:00 2001 From: somebodywashere <68244480+somebodywashere@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:09:14 +0300 Subject: [PATCH] [tgbot] Improvements, Additions and Fixes * Changed interaction with Expire Date for Clients * Added more info and interactions with Online Clients * Added a way to get Ban Logs (also added them to backup) * Few fixes and optimizations in code * Fixed RU translation --- web/service/inbound.go | 10 + web/service/tgbot.go | 447 ++++++++++++------------- web/translation/translate.en_US.toml | 19 +- web/translation/translate.es_ES.toml | 19 +- web/translation/translate.fa_IR.toml | 17 +- web/translation/translate.ru_RU.toml | 19 +- web/translation/translate.vi_VN.toml | 19 +- web/translation/translate.zh_Hans.toml | 17 +- 8 files changed, 310 insertions(+), 257 deletions(-) diff --git a/web/service/inbound.go b/web/service/inbound.go index bb4fe3c9..133fb268 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1146,6 +1146,8 @@ func (s *InboundService) SetClientTelegramUserID(trafficId int, tgId string) err if oldClient.Email == clientEmail { if inbound.Protocol == "trojan" { clientId = oldClient.Password + } else if inbound.Protocol == "shadowsocks" { + clientId = oldClient.Email } else { clientId = oldClient.ID } @@ -1231,6 +1233,8 @@ func (s *InboundService) ToggleClientEnableByEmail(clientEmail string) (bool, er if oldClient.Email == clientEmail { if inbound.Protocol == "trojan" { clientId = oldClient.Password + } else if inbound.Protocol == "shadowsocks" { + clientId = oldClient.Email } else { clientId = oldClient.ID } @@ -1292,6 +1296,8 @@ func (s *InboundService) ResetClientIpLimitByEmail(clientEmail string, count int if oldClient.Email == clientEmail { if inbound.Protocol == "trojan" { clientId = oldClient.Password + } else if inbound.Protocol == "shadowsocks" { + clientId = oldClient.Email } else { clientId = oldClient.ID } @@ -1350,6 +1356,8 @@ func (s *InboundService) ResetClientExpiryTimeByEmail(clientEmail string, expiry if oldClient.Email == clientEmail { if inbound.Protocol == "trojan" { clientId = oldClient.Password + } else if inbound.Protocol == "shadowsocks" { + clientId = oldClient.Email } else { clientId = oldClient.ID } @@ -1411,6 +1419,8 @@ func (s *InboundService) ResetClientTrafficLimitByEmail(clientEmail string, tota if oldClient.Email == clientEmail { if inbound.Protocol == "trojan" { clientId = oldClient.Password + } else if inbound.Protocol == "shadowsocks" { + clientId = oldClient.Email } else { clientId = oldClient.ID } diff --git a/web/service/tgbot.go b/web/service/tgbot.go index d77e2e71..97827e37 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -352,7 +352,7 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool inputNumber = 0 } else if num == -1 { if inputNumber > 0 { - inputNumber = (inputNumber / 10) ^ 0 + inputNumber = (inputNumber / 10) } } else { inputNumber = (inputNumber * 10) + num @@ -372,7 +372,7 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)), ), tu.InlineKeyboardRow( - tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" "+strconv.Itoa(inputNumber))), + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumberAdd", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" "+strconv.Itoa(inputNumber))), ), tu.InlineKeyboardRow( tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 1")), @@ -411,20 +411,20 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("reset_exp_in "+email+" 0")), ), tu.InlineKeyboardRow( - tu.InlineKeyboardButton("1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 30")), - tu.InlineKeyboardButton("2 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 60")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 7")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 10")), ), tu.InlineKeyboardRow( - tu.InlineKeyboardButton("3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 90")), - tu.InlineKeyboardButton("6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 180")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 14")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 20")), ), tu.InlineKeyboardRow( - tu.InlineKeyboardButton("9 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 270")), - tu.InlineKeyboardButton("12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 360")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 30")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 90")), ), tu.InlineKeyboardRow( - tu.InlineKeyboardButton("10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 10")), - tu.InlineKeyboardButton("20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 20")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 180")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 365")), ), ) t.editMessageCallbackTgBot(chatId, callbackQuery.Message.MessageID, inlineKeyboard) @@ -434,7 +434,29 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if err == nil { var date int64 = 0 if days > 0 { - date = int64(-(days * 24 * 60 * 60000)) + traffic, err := t.inboundService.GetClientTrafficByEmail(email) + if err != nil { + logger.Warning(err) + msg := t.I18nBot("tgbot.wentWrong") + t.SendMsgToTgbot(chatId, msg) + return + } + if traffic == nil { + msg := t.I18nBot("tgbot.noResult") + t.SendMsgToTgbot(chatId, msg) + return + } + + if traffic.ExpiryTime > 0 { + if traffic.ExpiryTime-time.Now().Unix()*1000 < 0 { + date = -int64(days * 24 * 60 * 60000) + } else { + date = traffic.ExpiryTime + int64(days*24*60*60000) + } + } else { + date = traffic.ExpiryTime - int64(days*24*60*60000) + } + } err := t.inboundService.ResetClientExpiryTimeByEmail(email, date) if err == nil { @@ -459,7 +481,7 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool inputNumber = 0 } else if num == -1 { if inputNumber > 0 { - inputNumber = (inputNumber / 10) ^ 0 + inputNumber = (inputNumber / 10) } } else { inputNumber = (inputNumber * 10) + num @@ -564,7 +586,7 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool inputNumber = 0 } else if num == -1 { if inputNumber > 0 { - inputNumber = (inputNumber / 10) ^ 0 + inputNumber = (inputNumber / 10) } } else { inputNumber = (inputNumber * 10) + num @@ -661,6 +683,16 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation")) } case "toggle_enable": + inlineKeyboard := tu.InlineKeyboard( + tu.InlineKeyboardRow( + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)), + ), + tu.InlineKeyboardRow( + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmToggle")).WithCallbackData(t.encodeQuery("toggle_enable_c "+email)), + ), + ) + t.editMessageCallbackTgBot(chatId, callbackQuery.Message.MessageID, inlineKeyboard) + case "toggle_enable_c": enabled, err := t.inboundService.ToggleClientEnableByEmail(email) if err == nil { t.xrayService.SetToNeedRestart() @@ -672,7 +704,6 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool t.searchClient(chatId, email, callbackQuery.Message.MessageID) } else { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation")) - logger.Error(err) } } return @@ -692,10 +723,14 @@ func (t *Tgbot) asnwerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool t.SendMsgToTgbot(chatId, t.getExhausted()) case "get_backup": t.sendBackup(chatId) + case "get_banlogs": + t.sendBanLogs(chatId, true) case "client_traffic": t.getClientUsage(chatId, callbackQuery.From.Username, strconv.FormatInt(callbackQuery.From.ID, 10)) case "client_commands": t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpClientCommands")) + case "onlines": + t.onlineClients(chatId) case "commands": t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpAdminCommands")) } @@ -714,7 +749,10 @@ func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) { numericKeyboard := tu.InlineKeyboard( tu.InlineKeyboardRow( tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.serverUsage")).WithCallbackData(t.encodeQuery("get_usage")), + ), + tu.InlineKeyboardRow( tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.dbBackup")).WithCallbackData(t.encodeQuery("get_backup")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.getBanLogs")).WithCallbackData(t.encodeQuery("get_banlogs")), ), tu.InlineKeyboardRow( tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.getInbounds")).WithCallbackData(t.encodeQuery("inbounds")), @@ -722,6 +760,7 @@ func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) { ), tu.InlineKeyboardRow( tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.commands")).WithCallbackData(t.encodeQuery("commands")), + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.onlines")).WithCallbackData(t.encodeQuery("onlines")), ), ) numericKeyboardClient := tu.InlineKeyboard( @@ -856,9 +895,11 @@ func (t *Tgbot) getServerUsage() string { // get latest status of server t.lastStatus = t.serverService.GetStatus(t.lastStatus) + onlines := p.GetOnlineClients() info += t.I18nBot("tgbot.messages.serverUpTime", "UpTime=="+strconv.FormatUint(t.lastStatus.Uptime/86400, 10), "Unit=="+t.I18nBot("tgbot.days")) info += t.I18nBot("tgbot.messages.serverLoad", "Load1=="+strconv.FormatFloat(t.lastStatus.Loads[0], 'f', 2, 64), "Load2=="+strconv.FormatFloat(t.lastStatus.Loads[1], 'f', 2, 64), "Load3=="+strconv.FormatFloat(t.lastStatus.Loads[2], 'f', 2, 64)) info += t.I18nBot("tgbot.messages.serverMemory", "Current=="+common.FormatTraffic(int64(t.lastStatus.Mem.Current)), "Total=="+common.FormatTraffic(int64(t.lastStatus.Mem.Total))) + info += t.I18nBot("tgbot.messages.onlinesCount", "Count=="+fmt.Sprint(len(onlines))) info += t.I18nBot("tgbot.messages.tcpCount", "Count=="+strconv.Itoa(t.lastStatus.TcpCount)) info += t.I18nBot("tgbot.messages.udpCount", "Count=="+strconv.Itoa(t.lastStatus.UdpCount)) info += t.I18nBot("tgbot.messages.traffic", "Total=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Sent+t.lastStatus.NetTraffic.Recv)), "Upload=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Sent)), "Download=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Recv))) @@ -920,6 +961,77 @@ func (t *Tgbot) getInboundUsages() string { return info } +func (t *Tgbot) clientInfoMsg(traffic *xray.ClientTraffic) string { + + now := time.Now().Unix() + expiryTime := "" + flag := false + diff := traffic.ExpiryTime/1000 - now + if traffic.ExpiryTime == 0 { + expiryTime = t.I18nBot("tgbot.unlimited") + } else if diff > 172800 || !traffic.Enable { + expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") + } else if traffic.ExpiryTime < 0 { + expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) + flag = true + } else { + expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) + flag = true + } + + total := "" + if traffic.Total == 0 { + total = t.I18nBot("tgbot.unlimited") + } else { + total = common.FormatTraffic((traffic.Total)) + } + + enabled := "" + isEnabled, err := t.inboundService.checkIsEnabledByEmail(traffic.Email) + if err != nil { + logger.Warning(err) + enabled = t.I18nBot("tgbot.wentWrong") + } else if isEnabled { + enabled = t.I18nBot("tgbot.messages.yes") + } else { + enabled = t.I18nBot("tgbot.messages.no") + } + + active := "" + if traffic.Enable { + active = t.I18nBot("tgbot.messages.yes") + } else { + active = t.I18nBot("tgbot.messages.no") + } + + status := t.I18nBot("tgbot.offline") + if p.IsRunning() { + for _, online := range p.GetOnlineClients() { + if online == traffic.Email { + status = t.I18nBot("tgbot.online") + break + } + } + } + + output := "" + output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) + output += t.I18nBot("tgbot.messages.enabled", "Enable=="+enabled) + output += t.I18nBot("tgbot.messages.online", "Status=="+status) + output += t.I18nBot("tgbot.messages.active", "Enable=="+active) + if flag { + output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) + } else { + output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) + } + output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) + output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) + output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) + output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) + + return output +} + func (t *Tgbot) getClientUsage(chatId int64, tgUserName string, tgUserID string) { traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID) if err != nil { @@ -949,48 +1061,8 @@ func (t *Tgbot) getClientUsage(chatId int64, tgUserName string, tgUserID string) return } - now := time.Now().Unix() for _, traffic := range traffics { - expiryTime := "" - flag := false - diff := traffic.ExpiryTime/1000 - now - if traffic.ExpiryTime == 0 { - expiryTime = t.I18nBot("tgbot.unlimited") - } else if diff > 172800 || !traffic.Enable { - expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") - } else if traffic.ExpiryTime < 0 { - expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) - flag = true - } else { - expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) - flag = true - } - - total := "" - if traffic.Total == 0 { - total = t.I18nBot("tgbot.unlimited") - } else { - total = common.FormatTraffic((traffic.Total)) - } - - output := "" - output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) - if traffic.Enable { - output += t.I18nBot("tgbot.messages.active") - if flag { - output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) - } else { - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - } else { - output += t.I18nBot("tgbot.messages.inactive") - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) - output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) - output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) - output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) - + output := t.clientInfoMsg(traffic) t.SendMsgToTgbot(chatId, output) } t.SendAnswer(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), false) @@ -1089,46 +1161,7 @@ func (t *Tgbot) searchClient(chatId int64, email string, messageID ...int) { return } - now := time.Now().Unix() - expiryTime := "" - flag := false - diff := traffic.ExpiryTime/1000 - now - if traffic.ExpiryTime == 0 { - expiryTime = t.I18nBot("tgbot.unlimited") - } else if diff > 172800 || !traffic.Enable { - expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") - } else if traffic.ExpiryTime < 0 { - expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) - flag = true - } else { - expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) - flag = true - } - - total := "" - if traffic.Total == 0 { - total = t.I18nBot("tgbot.unlimited") - } else { - total = common.FormatTraffic((traffic.Total)) - } - - output := "" - output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) - if traffic.Enable { - output += t.I18nBot("tgbot.messages.active") - if flag { - output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) - } else { - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - } else { - output += t.I18nBot("tgbot.messages.inactive") - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) - output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) - output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) - output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) + output := t.clientInfoMsg(traffic) inlineKeyboard := tu.InlineKeyboard( tu.InlineKeyboardRow( @@ -1174,7 +1207,6 @@ func (t *Tgbot) searchInbound(chatId int64, remark string) { return } - now := time.Now().Unix() for _, inbound := range inbouds { info := "" info += t.I18nBot("tgbot.messages.inbound", "Remark=="+inbound.Remark) @@ -1189,46 +1221,8 @@ func (t *Tgbot) searchInbound(chatId int64, remark string) { t.SendMsgToTgbot(chatId, info) for _, traffic := range inbound.ClientStats { - expiryTime := "" - flag := false - diff := traffic.ExpiryTime/1000 - now - if traffic.ExpiryTime == 0 { - expiryTime = t.I18nBot("tgbot.unlimited") - } else if diff > 172800 || !traffic.Enable { - expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") - } else if traffic.ExpiryTime < 0 { - expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) - flag = true - } else { - expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) - flag = true - } - - total := "" - if traffic.Total == 0 { - total = t.I18nBot("tgbot.unlimited") - } else { - total = common.FormatTraffic((traffic.Total)) - } - - output := "" - output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) - if traffic.Enable { - output += t.I18nBot("tgbot.messages.active") - if flag { - output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) - } else { - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - } else { - output += t.I18nBot("tgbot.messages.inactive") - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) - output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) - output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) - output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) + output := t.clientInfoMsg(&traffic) t.SendMsgToTgbot(chatId, output) } } @@ -1248,46 +1242,7 @@ func (t *Tgbot) searchForClient(chatId int64, query string) { return } - now := time.Now().Unix() - expiryTime := "" - flag := false - diff := traffic.ExpiryTime/1000 - now - if traffic.ExpiryTime == 0 { - expiryTime = t.I18nBot("tgbot.unlimited") - } else if diff > 172800 || !traffic.Enable { - expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") - } else if traffic.ExpiryTime < 0 { - expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) - flag = true - } else { - expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) - flag = true - } - - total := "" - if traffic.Total == 0 { - total = t.I18nBot("tgbot.unlimited") - } else { - total = common.FormatTraffic((traffic.Total)) - } - - output := "" - output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) - if traffic.Enable { - output += t.I18nBot("tgbot.messages.active") - if flag { - output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) - } else { - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - } else { - output += t.I18nBot("tgbot.messages.inactive") - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) - output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) - output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) - output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) + output := t.clientInfoMsg(traffic) t.SendMsgToTgbot(chatId, output) } @@ -1345,7 +1300,7 @@ func (t *Tgbot) getExhausted() string { output += "\r\n \r\n" if len(exhaustedInbounds) > 0 { - output += t.I18nBot("tgbot.messages.exhaustedMsg", "Type=="+t.I18nBot("tgbot.inbounds")) + output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+t.I18nBot("tgbot.inbounds")) for _, inbound := range exhaustedInbounds { output += t.I18nBot("tgbot.messages.inbound", "Remark=="+inbound.Remark) @@ -1367,47 +1322,10 @@ func (t *Tgbot) getExhausted() string { output += "\r\n \r\n" if len(exhaustedClients) > 0 { - output += t.I18nBot("tgbot.messages.exhaustedMsg", "Type=="+t.I18nBot("tgbot.clients")) + output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+t.I18nBot("tgbot.clients")) for _, traffic := range exhaustedClients { - expiryTime := "" - flag := false - diff := (traffic.ExpiryTime - now) / 1000 - if traffic.ExpiryTime == 0 { - expiryTime = t.I18nBot("tgbot.unlimited") - } else if diff > 172800 || !traffic.Enable { - expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05") - } else if traffic.ExpiryTime < 0 { - expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days")) - flag = true - } else { - expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours")) - flag = true - } - - total := "" - if traffic.Total == 0 { - total = t.I18nBot("tgbot.unlimited") - } else { - total = common.FormatTraffic((traffic.Total)) - } - - output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email) - if traffic.Enable { - output += t.I18nBot("tgbot.messages.active") - if flag { - output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime) - } else { - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - } else { - output += t.I18nBot("tgbot.messages.inactive") - output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime) - } - output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up)) - output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down)) - output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total) - output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05")) + output += t.clientInfoMsg(&traffic) output += "\r\n \r\n" } } @@ -1415,6 +1333,25 @@ func (t *Tgbot) getExhausted() string { return output } +func (t *Tgbot) onlineClients(chatId int64) { + if !p.IsRunning() { + return + } + + onlines := p.GetOnlineClients() + output := t.I18nBot("tgbot.messages.onlinesCount", "Count=="+fmt.Sprint(len(onlines))) + if len(onlines) > 0 { + keyboard := tu.InlineKeyboard() + for index, online := range onlines { + keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, tu.InlineKeyboardRow( + tu.InlineKeyboardButton(fmt.Sprintf("%d: %s\r\n", index+1, online)).WithCallbackData(t.encodeQuery("client_"+online)))) + } + t.SendMsgToTgbot(chatId, output, keyboard) + } else { + t.SendMsgToTgbot(chatId, output) + } +} + func (t *Tgbot) sendBackup(chatId int64) { output := t.I18nBot("tgbot.messages.backupTime", "Time=="+time.Now().Format("2006-01-02 15:04:05")) t.SendMsgToTgbot(chatId, output) @@ -1422,33 +1359,73 @@ func (t *Tgbot) sendBackup(chatId int64) { // Update by manually trigger a checkpoint operation err := database.Checkpoint() if err != nil { - logger.Warning("Error in trigger a checkpoint operation: ", err) + logger.Error("Error in trigger a checkpoint operation: ", err) } file, err := os.Open(config.GetDBPath()) - if err != nil { - logger.Warning("Error in opening db file for backup: ", err) - } - document := tu.Document( - tu.ID(chatId), - tu.File(file), - ) - _, err = bot.SendDocument(document) - if err != nil { - logger.Warning("Error in uploading backup: ", err) + if err == nil { + document := tu.Document( + tu.ID(chatId), + tu.File(file), + ) + _, err = bot.SendDocument(document) + if err != nil { + logger.Error("Error in uploading backup: ", err) + } + } else { + logger.Error("Error in opening db file for backup: ", err) + } file, err = os.Open(xray.GetConfigPath()) - if err != nil { - logger.Warning("Error in opening config.json file for backup: ", err) + if err == nil { + document := tu.Document( + tu.ID(chatId), + tu.File(file), + ) + _, err = bot.SendDocument(document) + if err != nil { + logger.Error("Error in uploading config.json: ", err) + } + } else { + logger.Error("Error in opening config.json file for backup: ", err) } - document = tu.Document( - tu.ID(chatId), - tu.File(file), - ) - _, err = bot.SendDocument(document) - if err != nil { - logger.Warning("Error in uploading config.json: ", err) + + t.sendBanLogs(chatId, false) +} + +func (t *Tgbot) sendBanLogs(chatId int64, dt bool) { + if dt { + output := t.I18nBot("tgbot.messages.datetime", "DateTime=="+time.Now().Format("2006-01-02 15:04:05")) + t.SendMsgToTgbot(chatId, output) + } + + file, err := os.Open(xray.GetIPLimitBannedPrevLogPath()) + if err == nil { + document := tu.Document( + tu.ID(chatId), + tu.File(file), + ) + _, err = bot.SendDocument(document) + if err != nil { + logger.Error("Error in uploading backup: ", err) + } + } else { + logger.Error("Error in opening db file for backup: ", err) + } + + file, err = os.Open(xray.GetIPLimitBannedLogPath()) + if err == nil { + document := tu.Document( + tu.ID(chatId), + tu.File(file), + ) + _, err = bot.SendDocument(document) + if err != nil { + logger.Error("Error in uploading config.json: ", err) + } + } else { + logger.Error("Error in opening config.json file for backup: ", err) } } diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 41df2454..f7d56d8b 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ No IP Record!" "noInbounds" = "❗ No inbound found!" "unlimited" = "♾ Unlimited" +"add" = "Add" "month" = "Month" "months" = "Months" "day" = "Day" @@ -445,6 +446,8 @@ "unknown" = "Unknown" "inbounds" = "Inbounds" "clients" = "Clients" +"offline" = "🔴 Offline" +"online" = "🟢 Online" [tgbot.commands] "unknown" = "❗ Unknown command" @@ -485,8 +488,9 @@ "port" = "🔌 Port: {{ .Port }}\r\n" "expire" = "📅 Expire Date: {{ .Time }}\r\n" "expireIn" = "📅 Expire In: {{ .Time }}\r\n" -"active" = "💡 Active: ✅ Yes\r\n" -"inactive" = "💡 Active: ❌ No\r\n" +"active" = "💡 Active: {{ .Enable }}\r\n" +"enabled" = "🚨 Enabled: {{ .Enable }}\r\n" +"online" = "🌐 Connection status: {{ .Status }}\r\n" "email" = "📧 Email: {{ .Email }}\r\n" "upload" = "🔼 Upload: ↑{{ .Upload }}\r\n" "download" = "🔽 Download: ↓{{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 Telegram User: {{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 Exhausted {{ .Type }}:\r\n" "exhaustedCount" = "🚨 Exhausted {{ .Type }} count:\r\n" +"onlinesCount" = "🌐 Online clients: {{ .Count }}\r\n" "disabled" = "🛑 Disabled: {{ .Disabled }}\r\n" "depleteSoon" = "🔜 Deplete Soon: {{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 Backup Time: {{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 Refreshed On: {{ .Time }}\r\n \r\n" +"yes" = "✅ Yes" +"no" = "❌ No" [tgbot.buttons] "closeKeyboard" = "❌ Close Keyboard" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ Confirm Reset Traffic?" "confirmClearIps" = "✅ Confirm Clear IPs?" "confirmRemoveTGUser" = "✅ Confirm Remove Telegram User?" +"confirmToggle" = "✅ Confirm Enable/Disable User?" "dbBackup" = "Get DB Backup" "serverUsage" = "Server Usage" "getInbounds" = "Get Inbounds" "depleteSoon" = "Deplete soon" "clientUsage" = "Get Usage" +"onlines" = "Online Clients" "commands" = "Commands" "refresh" = "🔄 Refresh" "clearIPs" = "❌ Clear IPs" @@ -519,14 +528,16 @@ "selectTGUser" = "👤 Select Telegram User" "selectOneTGUser" = "👤 Select a telegram user:" "resetTraffic" = "📈 Reset Traffic" -"resetExpire" = "📅 Reset Expire Days" +"resetExpire" = "📅 Change Expiration Date" "ipLog" = "🔢 IP Log" "ipLimit" = "🔢 IP Limit" "setTGUser" = "👤 Set Telegram User" "toggle" = "🔘 Enable / Disable" "custom" = "🔢 Custom" -"confirmNumber" = "✅ Confirm : {{ .Num }}" +"confirmNumber" = "✅ Confirm: {{ .Num }}" +"confirmNumberAdd" = "✅ Confirm adding: {{ .Num }}" "limitTraffic" = "🚧 Traffic Limit" +"getBanLogs" = "Get Ban Logs" [tgbot.answers] "successfulOperation" = "✅ Successful!" diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index 3e0ece57..90441f9a 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ ¡Sin Registro de IP!" "noInbounds" = "❗ ¡No se encontraron entradas!" "unlimited" = "♾ Ilimitado" +"add" = "Agregar" "month" = "Mes" "months" = "Meses" "day" = "Día" @@ -445,6 +446,8 @@ "unknown" = "Desconocido" "inbounds" = "Entradas" "clients" = "Clientes" +"offline" = "🔴 Sin conexión" +"online" = "🟢 En línea" [tgbot.commands] "unknown" = "❗ Comando desconocido" @@ -485,8 +488,9 @@ "port" = "🔌 Puerto: {{ .Port }}\r\n" "expire" = "📅 Fecha de Vencimiento: {{ .Time }}\r\n" "expireIn" = "📅 Vence en: {{ .Time }}\r\n" -"active" = "💡 Activo: ✅ Sí\r\n" -"inactive" = "💡 Activo: ❌ No\r\n" +"active" = "💡 Activo: {{ .Enable }}\r\n" +"enabled" = "🚨 Habilitado: {{ .Enable }}\r\n" +"online" = "🌐 Estado de conexión: {{ .Status }}\r\n" "email" = "📧 Email: {{ .Email }}\r\n" "upload" = "🔼 Subida: ↑{{ .Upload }}\r\n" "download" = "🔽 Bajada: ↓{{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 Usuario de Telegram: {{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 Agotado {{ .Type }}: \r\n" "exhaustedCount" = "🚨 Cantidad de Agotados {{ .Type }}: \r\n" +"onlinesCount" = "🌐 Clientes en línea: {{ .Count }}\r\n" "disabled" = "🛑 Desactivado: {{ .Disabled }}\r\n" "depleteSoon" = "🔜 Se agotará pronto: {{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 Hora de la Copia de Seguridad: {{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 Actualizado en: {{ .Time }}\r\n \r\n" +"yes" = "✅ Sí" +"no" = "❌ No" [tgbot.buttons] "closeKeyboard" = "❌ Cerrar Teclado" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ ¿Confirmar Reinicio de Tráfico?" "confirmClearIps" = "✅ ¿Confirmar Limpiar IPs?" "confirmRemoveTGUser" = "✅ ¿Confirmar Eliminar Usuario de Telegram?" +"confirmToggle" = " ✅ ¿Confirmar habilitar/deshabilitar usuario?" "dbBackup" = "Obtener Copia de Seguridad de BD" "serverUsage" = "Uso del Servidor" "getInbounds" = "Obtener Entradas" "depleteSoon" = "Pronto se Agotará" "clientUsage" = "Obtener Uso" +"onlines" = "Clientes en línea" "commands" = "Comandos" "refresh" = "🔄 Actualizar" "clearIPs" = "❌ Limpiar IPs" @@ -519,14 +528,16 @@ "selectTGUser" = "👤 Seleccionar Usuario de Telegram" "selectOneTGUser" = "👤 Selecciona un usuario de telegram:" "resetTraffic" = "📈 Reiniciar Tráfico" -"resetExpire" = "📅 Reiniciar Días de Vencimiento" +"resetExpire" = "📅 Cambiar fecha de Vencimiento" "ipLog" = "🔢 Registro de IP" "ipLimit" = "🔢 Límite de IP" "setTGUser" = "👤 Establecer Usuario de Telegram" "toggle" = "🔘 Habilitar / Deshabilitar" "custom" = "🔢 Costumbre" -"confirmNumber" = "✅ Confirmar : {{ .Num }}" +"confirmNumber" = "✅ Confirmar: {{ .Num }}" +"confirmNumberAdd" = "✅ Confirmar agregando: {{ .Num }}" "limitTraffic" = "🚧 Límite de tráfico" +"getBanLogs" = "Registros de prohibición" [tgbot.answers] "successfulOperation" = "✅ ¡Exitosa!" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 6597dd51..ea8f49e3 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ رکورد IP یافت نشد!" "noInbounds" = "❗ هیچ ورودی یافت نشد!" "unlimited" = "♾ نامحدود" +"add" = "اضافه کردن" "month" = "ماه" "months" = "ماه‌ها" "day" = "روز" @@ -445,6 +446,8 @@ "unknown" = "نامشخص" "inbounds" = "ورودی‌ها" "clients" = "کلاینت‌ها" +"offline" = "🔴 آفلاین" +"online" = "🟢 برخط" [tgbot.commands] "unknown" = "❗ دستور ناشناخته" @@ -485,8 +488,9 @@ "port" = "🔌 پورت: {{ .Port }}\r\n" "expire" = "📅 تاریخ انقضا: {{ .Time }}\r\n" "expireIn" = "📅 باقیمانده از انقضا: {{ .Time }}\r\n" -"active" = "💡 فعال: ✅\r\n" -"inactive" = "💡 فعال: ❌\r\n" +"active" = "💡 فعال: {{ .Enable }}\r\n" +"enabled" = "🚨 مشمول: {{ .Enable }}\r\n" +"online" = "🌐 وضعیت اتصال: {{ .Status }}\r\n" "email" = "📧 ایمیل: {{ .Email }}\r\n" "upload" = "🔼 آپلود↑: {{ .Upload }}\r\n" "download" = "🔽 دانلود↓: {{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 کاربر تلگرام: {{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 {{ .Type }} به اتمام رسیده است:\r\n" "exhaustedCount" = "🚨 تعداد {{ .Type }} به اتمام رسیده:\r\n" +"onlinesCount" = "🌐 مشتریان آنلاین: {{ .Count }}\r\n" "disabled" = "🛑 غیرفعال: {{ .Disabled }}\r\n" "depleteSoon" = "🔜 به زودی به پایان خواهد رسید: {{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 زمان پشتیبان‌گیری: {{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 تازه‌سازی شده در: {{ .Time }}\r\n \r\n" +"yes" = "✅ بله" +"no" = "❌ نه" [tgbot.buttons] "closeKeyboard" = "❌ بستن کیبورد" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ تأیید تنظیم مجدد ترافیک؟" "confirmClearIps" = "✅ تأیید پاک‌سازی آدرس‌های IP؟" "confirmRemoveTGUser" = "✅ تأیید حذف کاربر تلگرام؟" +"confirmToggle" = "✅ تایید فعال/غیرفعال کردن کاربر؟" "dbBackup" = "دریافت پشتیبان پایگاه داده" "serverUsage" = "استفاده از سرور" "getInbounds" = "دریافت ورودی‌ها" "depleteSoon" = "به زودی به پایان خواهد رسید" "clientUsage" = "دریافت آمار کاربر" +"onlines" = "مشتریان آنلاین" "commands" = "دستورات" "refresh" = "🔄 تازه‌سازی" "clearIPs" = "❌ پاک‌سازی آدرس‌ها" @@ -525,8 +534,10 @@ "setTGUser" = "👤 تنظیم کاربر تلگرام" "toggle" = "🔘 فعال / غیرفعال" "custom" = "🔢 سفارشی" -"confirmNumber" = "✅ تایید : {{ .Num }}" +"confirmNumber" = "✅ تایید: {{ .Num }}" +"confirmNumberAdd" = "✅ تایید اضافه کردن: {{ .Num }}" "limitTraffic" = "🚧 محدودیت ترافیک" +"getBanLogs" = "گزارش های بلوک را دریافت کنید" [tgbot.answers] "successfulOperation" = "✅ انجام شد!" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index 852bc5ed..d8f4fbb9 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ Нет записей об IP-адресе!" "noInbounds" = "❗ Входящих соединений не найдено!" "unlimited" = "♾ Неограниченно" +"add" = "Добавить" "month" = "Месяц" "months" = "Месяцев" "day" = "День" @@ -445,6 +446,8 @@ "unknown" = "Неизвестно" "inbounds" = "Входящие" "clients" = "Клиенты" +"offline" = "🔴 Офлайн" +"online" = "🟢 Онлайн" [tgbot.commands] "unknown" = "❗ Неизвестная команда" @@ -486,7 +489,8 @@ "expire" = "📅 Дата окончания: {{ .Time }}\r\n" "expireIn" = "📅 Окончание через: {{ .Time }}\r\n" "active" = "💡 Активен: ✅ Да\r\n" -"inactive" = "💡 Активен: ❌ Нет\r\n" +"enabled" = "🚨 Включен: {{ .Enable }}\r\n" +"online" = "🌐 Статус соединения: {{ .Status }}\r\n" "email" = "📧 Email: {{ .Email }}\r\n" "upload" = "🔼 Исходящий трафик: ↑{{ .Upload }}\r\n" "download" = "🔽 Входящий трафик: ↓{{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 Пользователь Telegram: {{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 Исчерпаны {{ .Type }}:\r\n" "exhaustedCount" = "🚨 Количество исчерпанных {{ .Type }}:\r\n" +"onlinesCount" = "🌐 Клиентов онлайн: {{ .Count }}\r\n" "disabled" = "🛑 Отключено: {{ .Disabled }}\r\n" "depleteSoon" = "🔜 Скоро исчерпание: {{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 Время резервного копирования: {{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 Обновлено: {{ .Time }}\r\n \r\n" +"yes" = "✅ Да" +"no" = "❌ Нет" [tgbot.buttons] "closeKeyboard" = "❌ Закрыть клавиатуру" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ Подтвердить сброс трафика?" "confirmClearIps" = "✅ Подтвердить очистку IP?" "confirmRemoveTGUser" = "✅ Подтвердить удаление пользователя Telegram?" +"confirmToggle" = "✅ Подтвердить вкл/выкл пользователя?" "dbBackup" = "Получить резервную копию DB" "serverUsage" = "Использование сервера" "getInbounds" = "Получить входящие потоки" "depleteSoon" = "Скоро исчерпание" "clientUsage" = "Получить использование" +"onlines" = "Онлайн-клиенты" "commands" = "Команды" "refresh" = "🔄 Обновить" "clearIPs" = "❌ Очистить IP" @@ -519,14 +528,16 @@ "selectTGUser" = "👤 Выбрать пользователя Telegram" "selectOneTGUser" = "👤 Выберите пользователя Telegram:" "resetTraffic" = "📈 Сбросить трафик" -"resetExpire" = "📅 Сбросить дату окончания" +"resetExpire" = "📅 Изменить дату окончания" "ipLog" = "🔢 Лог IP" "ipLimit" = "🔢 Лимит IP" "setTGUser" = "👤 Установить пользователя Telegram" "toggle" = "🔘 Вкл./Выкл." -"custom" = "🔢 Обычай" -"confirmNumber" = "✅ Подтвердить : {{ .Num }}" +"custom" = "🔢 Свой" +"confirmNumber" = "✅ Подтвердить: {{ .Num }}" +"confirmNumberAdd" = "✅ Подтвердить добавление: {{ .Num }}" "limitTraffic" = "🚧 Лимит трафика" +"getBanLogs" = "Логи блокировок" [tgbot.answers] "successfulOperation" = "✅ Успешный!" diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index 122357d8..c3165d88 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ Không có bản ghi IP!" "noInbounds" = "❗ Không tìm thấy inbound!" "unlimited" = "♾ Không giới hạn" +"add" = "Thêm" "month" = "Tháng" "months" = "Tháng" "day" = "Ngày" @@ -445,6 +446,8 @@ "unknown" = "Không rõ" "inbounds" = "Vào" "clients" = "Các khách hàng" +"offline" = "🔴 Ngoại tuyến" +"online" = "🟢 Trực tuyến" [tgbot.commands] "unknown" = "❗ Lệnh không rõ" @@ -485,8 +488,9 @@ "port" = "🔌 Cổng: {{ .Port }}\r\n" "expire" = "📅 Ngày hết hạn: {{ .Time }}\r\n" "expireIn" = "📅 Hết hạn sau: {{ .Time }}\r\n" -"active" = "💡 Hoạt động: ✅ Có\r\n" -"inactive" = "💡 Hoạt động: ❌ Không\r\n" +"active" = "💡 Đang hoạt động: {{ .Enable }}\r\n" +"enabled" = "🚨 Đã bật: {{ .Enable }}\r\n" +"online" = "🌐 Trạng thái kết nối: {{ .Status }}\r\n" "email" = "📧 Email: {{ .Email }}\r\n" "upload" = "🔼 Tải lên: ↑{{ .Upload }}\r\n" "download" = "🔽 Tải xuống: ↓{{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 Người dùng Telegram: {{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 Sự cạn kiệt {{ .Type }}:\r\n" "exhaustedCount" = "🚨 Số lần cạn kiệt {{ .Type }}:\r\n" +"onlinesCount" = "🌐 Khách hàng trực tuyến: {{ .Count }}\r\n" "disabled" = "🛑 Vô hiệu hóa: {{ .Disabled }}\r\n" "depleteSoon" = "🔜 Sắp cạn kiệt: {{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 Thời gian sao lưu: {{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 Đã cập nhật lần cuối vào: {{ .Time }}\r\n \r\n" +"yes" = "✅ Có" +"no" = "❌ Không" [tgbot.buttons] "closeKeyboard" = "❌ Đóng Bàn Phím" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ Xác Nhận Đặt Lại Lưu Lượng?" "confirmClearIps" = "✅ Xác Nhận Xóa Các IP?" "confirmRemoveTGUser" = "✅ Xác Nhận Xóa Người Dùng Telegram?" +"confirmToggle" = "✅ Xác nhận Bật/Tắt người dùng?" "dbBackup" = "Tải bản sao lưu cơ sở dữ liệu" "serverUsage" = "Sử Dụng Máy Chủ" "getInbounds" = "Lấy cổng vào" "depleteSoon" = "Depleted Soon" "clientUsage" = "Lấy Sử Dụng" +"onlines" = "Khách hàng trực tuyến" "commands" = "Lệnh" "refresh" = "🔄 Cập Nhật" "clearIPs" = "❌ Xóa IP" @@ -519,14 +528,16 @@ "selectTGUser" = "👤 Chọn Người Dùng Telegram" "selectOneTGUser" = "👤 Chọn một người dùng telegram:" "resetTraffic" = "📈 Đặt Lại Lưu Lượng" -"resetExpire" = "📅 Đặt Lại Ngày Hết Hạn" +"resetExpire" = "📅 Thay đổi ngày hết hạn" "ipLog" = "🔢 Nhật ký địa chỉ IP" "ipLimit" = "🔢 Giới Hạn địa chỉ IP" "setTGUser" = "👤 Đặt Người Dùng Telegram" "toggle" = "🔘 Bật / Tắt" "custom" = "🔢 Tùy chỉnh" -"confirmNumber" = "✅ Xác nhận : {{ .Num }}" +"confirmNumber" = "✅ Xác nhận: {{ .Num }}" +"confirmNumberAdd" = "✅ Xác nhận thêm: {{ .Num }}" "limitTraffic" = "🚧 Giới hạn lưu lượng" +"getBanLogs" = "Cấm nhật ký" [tgbot.answers] "successfulOperation" = "✅ Thành công!" diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml index 066e4991..c0b8330e 100644 --- a/web/translation/translate.zh_Hans.toml +++ b/web/translation/translate.zh_Hans.toml @@ -437,6 +437,7 @@ "noIpRecord" = "❗ 没有IP记录!" "noInbounds" = "❗ 没有找到入站连接!" "unlimited" = "♾ 无限制" +"add" = "添加" "month" = "月" "months" = "月" "day" = "天" @@ -445,6 +446,8 @@ "unknown" = "未知" "inbounds" = "入站连接" "clients" = "客户端" +"offline" = "🔴 离线" +"online" = "🟢 在线的" [tgbot.commands] "unknown" = "❗ 未知命令" @@ -486,7 +489,8 @@ "expire" = "📅 过期日期:{{ .Time }}\r\n" "expireIn" = "📅 剩余时间:{{ .Time }}\r\n" "active" = "💡 激活:✅\r\n" -"inactive" = "💡 激活: ❌\r\n" +"enabled" = "🚨 已启用:{{ .Enable }}\r\n" +"online" = "🌐 连接状态:{{ .Status }}\r\n" "email" = "📧 邮箱:{{ .Email }}\r\n" "upload" = "🔼 上传↑:{{ .Upload }}\r\n" "download" = "🔽 下载↓:{{ .Download }}\r\n" @@ -494,10 +498,13 @@ "TGUser" = "👤 电报用户:{{ .TelegramID }}\r\n" "exhaustedMsg" = "🚨 耗尽的{{ .Type }}:\r\n" "exhaustedCount" = "🚨 耗尽的{{ .Type }}数量:\r\n" +"onlinesCount" = "🌐 在线客户:{{ .Count }}\r\n" "disabled" = "🛑 禁用:{{ .Disabled }}\r\n" "depleteSoon" = "🔜 即将耗尽:{{ .Deplete }}\r\n \r\n" "backupTime" = "🗄 备份时间:{{ .Time }}\r\n" "refreshedOn" = "\r\n📋🔄 刷新时间:{{ .Time }}\r\n \r\n" +"yes" = "✅ 是的" +"no" = "❌ 没有" [tgbot.buttons] "closeKeyboard" = "❌ 关闭键盘" @@ -507,11 +514,13 @@ "confirmResetTraffic" = "✅ 确认重置流量?" "confirmClearIps" = "✅ 确认清除 IP?" "confirmRemoveTGUser" = "✅ 确认移除 Telegram 用户?" +"confirmToggle" = "✅ 确认启用/禁用用户?" "dbBackup" = "获取数据库备份" "serverUsage" = "服务器使用情况" "getInbounds" = "获取入站信息" "depleteSoon" = "即将耗尽" "clientUsage" = "获取使用情况" +"onlines" = "在线客户" "commands" = "命令" "refresh" = "🔄 刷新" "clearIPs" = "❌ 清除 IP" @@ -519,14 +528,16 @@ "selectTGUser" = "👤 选择 Telegram 用户" "selectOneTGUser" = "👤 选择一个 Telegram 用户:" "resetTraffic" = "📈 重置流量" -"resetExpire" = "📅 重置过期天数" +"resetExpire" = "📅 更改到期日期" "ipLog" = "🔢 IP 日志" "ipLimit" = "🔢 IP 限制" "setTGUser" = "👤 设置 Telegram 用户" "toggle" = "🔘 启用/禁用" "custom" = "🔢 风俗" -"confirmNumber" = "✅ 确认 : {{ .Num }}" +"confirmNumber" = "✅ 确认: {{ .Num }}" +"confirmNumberAdd" = "✅ 确认添加:{{ .Num }}" "limitTraffic" = "🚧 交通限制" +"getBanLogs" = "禁止日志" [tgbot.answers] "successfulOperation" = "✅ 成功的!"