mirror of
https://github.com/alireza0/x-ui.git
synced 2026-03-16 22:09:45 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4838b0f6f0 | ||
|
|
bb8807129a | ||
|
|
cb050bfe34 | ||
|
|
76a996cc2d | ||
|
|
7fec1dd5cf | ||
|
|
a24e9089b6 | ||
|
|
b6474eaef6 | ||
|
|
76f90b0a46 | ||
|
|
42abffdaef |
@@ -10,8 +10,11 @@ else
|
||||
FNAME="amd64";
|
||||
fi
|
||||
mkdir -p build/bin
|
||||
cd build/bin
|
||||
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.1/Xray-linux-${ARCH}.zip"
|
||||
wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" -o build/bin/geoip.dat
|
||||
wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -o build/bin/geosite.dat
|
||||
mv xray "build/bin/xray-linux-${FNAME}"
|
||||
mv main build/x-ui
|
||||
unzip "Xray-linux-${ARCH}.zip"
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||
mv xray "xray-linux-${FNAME}"
|
||||
wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat"
|
||||
wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
|
||||
cd ../../
|
||||
@@ -1,9 +1,9 @@
|
||||
FROM golang:1.20-alpine AS builder
|
||||
WORKDIR /app
|
||||
ARG TARGETARCH
|
||||
RUN apk --no-cache --update add build-base gcc wget
|
||||
RUN apk --no-cache --update add build-base gcc wget unzip
|
||||
COPY . .
|
||||
RUN env CGO_ENABLED=1 go build main.go
|
||||
RUN env CGO_ENABLED=1 go build -o build/x-ui main.go
|
||||
RUN ./DockerInitFiles.sh "$TARGETARCH"
|
||||
|
||||
FROM alpine
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.0.0
|
||||
1.0.1
|
||||
8
main.go
8
main.go
@@ -51,8 +51,8 @@ func runWebServer() {
|
||||
}
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
//信号量捕获处理
|
||||
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL)
|
||||
// Trap shutdown signals
|
||||
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM)
|
||||
for {
|
||||
sig := <-sigCh
|
||||
|
||||
@@ -133,7 +133,6 @@ func updateTgbotEnableSts(status bool) {
|
||||
logger.Infof("SetTgbotenabled[%v] success", status)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) {
|
||||
@@ -290,6 +289,9 @@ func main() {
|
||||
if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
|
||||
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
|
||||
}
|
||||
if enabletgbot {
|
||||
updateTgbotEnableSts(enabletgbot)
|
||||
}
|
||||
default:
|
||||
fmt.Println("except 'run' or 'v2-ui' or 'setting' subcommands")
|
||||
fmt.Println()
|
||||
|
||||
@@ -647,7 +647,7 @@ class RealityStreamSettings extends XrayCommonClass {
|
||||
}
|
||||
|
||||
RealityStreamSettings.Settings = class extends XrayCommonClass {
|
||||
constructor(publicKey = '', fingerprint = '', serverName = '', spiderX= '/') {
|
||||
constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_FIREFOX, serverName = '', spiderX= '/') {
|
||||
super();
|
||||
this.publicKey = publicKey;
|
||||
this.fingerprint = fingerprint;
|
||||
@@ -1243,15 +1243,13 @@ class Inbound extends XrayCommonClass {
|
||||
if (this.reality) {
|
||||
params.set("security", "reality");
|
||||
params.set("pbk", this.stream.reality.settings.publicKey);
|
||||
params.set("fp", this.stream.reality.settings.fingerprint);
|
||||
if (!ObjectUtil.isArrEmpty(this.stream.reality.serverNames)) {
|
||||
params.set("sni", this.stream.reality.serverNames.split(",")[0]);
|
||||
}
|
||||
if (this.stream.reality.shortIds.length > 0) {
|
||||
params.set("sid", this.stream.reality.shortIds.split(",")[0]);
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(this.stream.reality.fingerprint)) {
|
||||
params.set("fp", this.stream.reality.settings.fingerprint);
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
|
||||
address = this.stream.reality.settings.serverName;
|
||||
}
|
||||
@@ -1355,15 +1353,13 @@ class Inbound extends XrayCommonClass {
|
||||
if (this.reality) {
|
||||
params.set("security", "reality");
|
||||
params.set("pbk", this.stream.reality.settings.publicKey);
|
||||
params.set("fp", this.stream.reality.settings.fingerprint);
|
||||
if (!ObjectUtil.isArrEmpty(this.stream.reality.serverNames)) {
|
||||
params.set("sni", this.stream.reality.serverNames.split(",")[0]);
|
||||
}
|
||||
if (this.stream.reality.shortIds.length > 0) {
|
||||
params.set("sid", this.stream.reality.shortIds.split(",")[0]);
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(this.stream.reality.fingerprint)) {
|
||||
params.set("fp", this.stream.reality.settings.fingerprint);
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
|
||||
address = this.stream.reality.settings.serverName;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func (a *SUBController) subs(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Add subscription-userinfo
|
||||
c.Writer.Header().Set("subscription-userinfo", header)
|
||||
c.Writer.Header().Set("Subscription-Userinfo", header)
|
||||
|
||||
c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
|
||||
}
|
||||
|
||||
@@ -122,6 +122,24 @@
|
||||
}
|
||||
client.email = string;
|
||||
},
|
||||
resetClientTraffic(email,dbInboundId,iconElement) {
|
||||
this.$confirm({
|
||||
title: '{{ i18n "pages.inbounds.resetTraffic"}}',
|
||||
content: '{{ i18n "pages.inbounds.resetTrafficContent"}}',
|
||||
class: siderDrawer.isDarkTheme ? darkClass : '',
|
||||
okText: '{{ i18n "reset"}}',
|
||||
cancelText: '{{ i18n "cancel"}}',
|
||||
onOk: async () => {
|
||||
iconElement.disabled = true;
|
||||
const msg = await HttpUtil.postWithModal('/xui/inbound/' + dbInboundId + '/resetClientTraffic/'+ email);
|
||||
if (msg.success) {
|
||||
this.clientModal.clientStats.up = 0;
|
||||
this.clientModal.clientStats.down = 0;
|
||||
}
|
||||
iconElement.disabled = false;
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<a-input :value="value" @input="$emit('input', $event.target.value)"></a-input>
|
||||
</template>
|
||||
<template v-else-if="type === 'number'">
|
||||
<a-input-number :value="value" @input="$emit('input', $event.target.value)"></a-input-number>
|
||||
<a-input type="number" :value="value" @input="$emit('input', $event.target.value)"></a-input>
|
||||
</template>
|
||||
<template v-else-if="type === 'textarea'">
|
||||
<a-textarea :value="value" @input="$emit('input', $event.target.value)" :auto-size="{ minRows: 10, maxRows: 10 }"></a-textarea>
|
||||
|
||||
@@ -103,6 +103,10 @@
|
||||
[[ sizeFormat(clientStats.down) ]]
|
||||
([[ sizeFormat(clientStats.up + clientStats.down) ]])
|
||||
</a-tag>
|
||||
<a-tooltip>
|
||||
<template slot="title">{{ i18n "pages.inbounds.resetTraffic" }}</template>
|
||||
<a-icon type="retweet" @click="resetClientTraffic(client.email,clientStats.inboundId,$event.target)" v-if="client.email.length > 0"></a-icon>
|
||||
</a-tooltip>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
{{define "form/streamSettings"}}
|
||||
<!-- select stream network -->
|
||||
<a-form layout="inline">
|
||||
<table width="100%" class="ant-table-tbody">
|
||||
<tr>
|
||||
<td>{{ i18n "transmission" }}</td>
|
||||
<td>
|
||||
<a-form-item>
|
||||
<a-select v-model="inbound.stream.network" @change="streamNetworkChange"
|
||||
:dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''">
|
||||
<a-select-option value="tcp">tcp</a-select-option>
|
||||
<a-select-option value="kcp">kcp</a-select-option>
|
||||
<a-select-option value="ws">ws</a-select-option>
|
||||
<a-select-option value="http">http</a-select-option>
|
||||
<a-select-option value="quic">quic</a-select-option>
|
||||
<a-select-option value="grpc">grpc</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a-form-item label="{{ i18n "transmission" }}">
|
||||
<a-select v-model="inbound.stream.network" @change="streamNetworkChange"
|
||||
:dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''">
|
||||
<a-select-option value="tcp">tcp</a-select-option>
|
||||
<a-select-option value="kcp">kcp</a-select-option>
|
||||
<a-select-option value="ws">ws</a-select-option>
|
||||
<a-select-option value="http">http</a-select-option>
|
||||
<a-select-option value="quic">quic</a-select-option>
|
||||
<a-select-option value="grpc">grpc</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- tcp -->
|
||||
|
||||
@@ -176,7 +176,6 @@
|
||||
<td>
|
||||
<a-form-item >
|
||||
<a-select v-model="inbound.stream.reality.settings.fingerprint" style="width: 250px">
|
||||
<a-select-option value=''>None</a-select-option>
|
||||
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</td>
|
||||
<td v-else-if="inbound.reality">
|
||||
reality: <a-tag color="green">{{ i18n "enabled" }}</a-tag><br />
|
||||
reality {{ i18n "domainName" }}: <a-tag :color="inbound.serverName ? 'green' : 'orange'">[[ inbound.serverName ? inbound.serverName : '' ]]</a-tag>
|
||||
reality Destination: <a-tag :color="inbound.stream.reality.dest ? 'green' : 'orange'">[[ inbound.stream.reality.dest ]]</a-tag>
|
||||
</td>
|
||||
<td v-else>tls: <a-tag color="red">{{ i18n "disabled" }}</a-tag>
|
||||
</td>
|
||||
|
||||
@@ -66,13 +66,7 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, string, error
|
||||
}
|
||||
}
|
||||
}
|
||||
header = fmt.Sprintf("upload=%d;download=%d", traffic.Up, traffic.Down)
|
||||
if traffic.Total > 0 {
|
||||
header = header + fmt.Sprintf(";total=%d", traffic.Total)
|
||||
}
|
||||
if traffic.ExpiryTime > 0 {
|
||||
header = header + fmt.Sprintf(";expire=%d", traffic.ExpiryTime)
|
||||
}
|
||||
header = fmt.Sprintf("upload=%d; download=%d; total=%d; expire=%d", traffic.Up, traffic.Down, traffic.Total, traffic.ExpiryTime/1000)
|
||||
return result, header, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user