Skip to content

Commit c00d51a

Browse files
committed
feat: add custom geosite/geoip URL sources
Register DB model, panel API, index/xray UI, and i18n.
1 parent 38d8723 commit c00d51a

30 files changed

+1973
-14
lines changed

README.ar_EG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
كمشروع محسن من مشروع X-UI الأصلي، يوفر 3X-UI استقرارًا محسنًا ودعمًا أوسع للبروتوكولات وميزات إضافية.
2424

25+
## مصادر DAT مخصصة GeoSite / GeoIP
26+
27+
يمكن للمسؤولين إضافة ملفات `.dat` لـ GeoSite وGeoIP من عناوين URL في اللوحة (نفس أسلوب تحديث ملفات الجيو المدمجة). تُحفظ الملفات بجانب ثنائي Xray (`XUI_BIN_FOLDER`، الافتراضي `bin/`) بأسماء ثابتة: `geosite_<alias>.dat` و`geoip_<alias>.dat`.
28+
29+
**التوجيه:** استخدم الصيغة `ext:`، مثل `ext:geosite_myalias.dat:tag` أو `ext:geoip_myalias.dat:tag`، حيث `tag` اسم قائمة داخل ملف DAT (كما في `ext:geoip_IR.dat:ir`).
30+
31+
**الأسماء المحجوزة:** يُقارَن شكل مُطبَّع فقط لمعرفة التحفظ (`strings.ToLower`، `-``_`). لا تُعاد كتابة الأسماء التي يدخلها المستخدم أو سجلات قاعدة البيانات؛ يجب أن تطابق `^[a-z0-9_-]+$`. مثلاً `geoip-ir` و`geoip_ir` يصطدمان بنفس الحجز.
32+
2533
## البدء السريع
2634

2735
```

README.es_ES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
Como una versión mejorada del proyecto X-UI original, 3X-UI proporciona mayor estabilidad, soporte más amplio de protocolos y características adicionales.
2424

25+
## Fuentes DAT personalizadas GeoSite / GeoIP
26+
27+
Los administradores pueden añadir archivos `.dat` de GeoSite y GeoIP desde URLs en el panel (mismo flujo que los geoficheros integrados). Los archivos se guardan junto al binario de Xray (`XUI_BIN_FOLDER`, por defecto `bin/`) con nombres fijos: `geosite_<alias>.dat` y `geoip_<alias>.dat`.
28+
29+
**Enrutamiento:** use la forma `ext:`, por ejemplo `ext:geosite_myalias.dat:tag` o `ext:geoip_myalias.dat:tag`, donde `tag` es un nombre de lista dentro del DAT (igual que en archivos regionales como `ext:geoip_IR.dat:ir`).
30+
31+
**Alias reservados:** solo para comprobar si un nombre está reservado se compara una forma normalizada (`strings.ToLower`, `-``_`). Los alias introducidos y los nombres en la base de datos no se reescriben; deben cumplir `^[a-z0-9_-]+$`. Por ejemplo, `geoip-ir` y `geoip_ir` chocan con la misma entrada reservada.
32+
2533
## Inicio Rápido
2634

2735
```

README.fa_IR.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
به عنوان یک نسخه بهبود یافته از پروژه اصلی X-UI، 3X-UI پایداری بهتر، پشتیبانی گسترده‌تر از پروتکل‌ها و ویژگی‌های اضافی را ارائه می‌دهد.
2424

25+
## منابع DAT سفارشی GeoSite / GeoIP
26+
27+
سرپرستان می‌توانند از طریق پنل فایل‌های `.dat` GeoSite و GeoIP را از URL اضافه کنند (همان الگوی به‌روزرسانی ژئوفایل‌های داخلی). فایل‌ها در کنار باینری Xray (`XUI_BIN_FOLDER`، پیش‌فرض `bin/`) با نام‌های ثابت `geosite_<alias>.dat` و `geoip_<alias>.dat` ذخیره می‌شوند.
28+
29+
**مسیریابی:** از شکل `ext:` استفاده کنید، مثلاً `ext:geosite_myalias.dat:tag` یا `ext:geoip_myalias.dat:tag`؛ `tag` نام لیست داخل همان DAT است (مانند `ext:geoip_IR.dat:ir`).
30+
31+
**نام‌های رزرو:** فقط برای تشخیص رزرو بودن، نسخه نرمال‌شده (`strings.ToLower`، `-``_`) مقایسه می‌شود. نام‌های واردشده و رکورد پایگاه داده بازنویسی نمی‌شوند و باید با `^[a-z0-9_-]+$` سازگار باشند؛ مثلاً `geoip-ir` و `geoip_ir` به یک رزرو یکسان می‌خورند.
32+
2533
## شروع سریع
2634

2735
```

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
As an enhanced fork of the original X-UI project, 3X-UI provides improved stability, broader protocol support, and additional features.
2424

25+
## Custom GeoSite / GeoIP DAT sources
26+
27+
Administrators can add custom GeoSite and GeoIP `.dat` files from URLs in the panel (same workflow as updating built-in geofiles). Files are stored under the same directory as the Xray binary (`XUI_BIN_FOLDER`, default `bin/`) with deterministic names: `geosite_<alias>.dat` and `geoip_<alias>.dat`.
28+
29+
**Routing:** Xray resolves extra lists using the `ext:` form, for example `ext:geosite_myalias.dat:tag` or `ext:geoip_myalias.dat:tag`, where `tag` is a list name inside that DAT file (same pattern as built-in regional files such as `ext:geoip_IR.dat:ir`).
30+
31+
**Reserved aliases:** Only for deciding whether a name is reserved, the panel compares a normalized form of the alias (`strings.ToLower`, `-``_`). User-entered aliases and generated file names are not rewritten in the database; they must still match `^[a-z0-9_-]+$`. For example, `geoip-ir` and `geoip_ir` collide with the same reserved entry.
32+
2533
## Quick Start
2634

2735
```bash

README.ru_RU.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
Как улучшенная версия оригинального проекта X-UI, 3X-UI обеспечивает повышенную стабильность, более широкую поддержку протоколов и дополнительные функции.
2424

25+
## Пользовательские GeoSite / GeoIP (DAT)
26+
27+
В панели можно задать свои источники `.dat` по URL (тот же сценарий, что и для встроенных геофайлов). Файлы сохраняются в каталоге с бинарником Xray (`XUI_BIN_FOLDER`, по умолчанию `bin/`) как `geosite_<alias>.dat` и `geoip_<alias>.dat`.
28+
29+
**Маршрутизация:** в правилах используйте форму `ext:имя_файла.dat:тег`, например `ext:geosite_myalias.dat:tag` (как у региональных списков `ext:geoip_IR.dat:ir`).
30+
31+
**Зарезервированные псевдонимы:** только для проверки на резерв используется нормализованная форма (`strings.ToLower`, `-``_`). Введённые пользователем псевдонимы и имена файлов в БД не переписываются и должны соответствовать `^[a-z0-9_-]+$`. Например, `geoip-ir` и `geoip_ir` попадают под одну и ту же зарезервированную запись.
32+
2533
## Быстрый старт
2634

2735
```

README.zh_CN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
2323
作为原始 X-UI 项目的增强版本,3X-UI 提供了更好的稳定性、更广泛的协议支持和额外的功能。
2424

25+
## 自定义 GeoSite / GeoIP(DAT)
26+
27+
管理员可在面板中从 URL 添加自定义 GeoSite 与 GeoIP `.dat` 文件(与内置地理文件相同的管理流程)。文件保存在 Xray 可执行文件所在目录(`XUI_BIN_FOLDER`,默认 `bin/`),文件名为 `geosite_<alias>.dat``geoip_<alias>.dat`
28+
29+
**路由:** 在规则中使用 `ext:` 形式,例如 `ext:geosite_myalias.dat:tag``ext:geoip_myalias.dat:tag`,其中 `tag` 为该 DAT 文件内的列表名(与内置区域文件如 `ext:geoip_IR.dat:ir` 相同)。
30+
31+
**保留别名:** 仅在为判断是否命中保留名时,会对别名做规范化比较(`strings.ToLower``-``_`)。用户输入的别名与数据库中的名称不会被改写,且须符合 `^[a-z0-9_-]+$`。例如 `geoip-ir``geoip_ir` 视为同一保留项。
32+
2533
## 快速开始
2634

2735
```

database/db.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func initModels() error {
3838
&model.InboundClientIps{},
3939
&xray.ClientTraffic{},
4040
&model.HistoryOfSeeders{},
41+
&model.CustomGeoResource{},
4142
}
4243
for _, model := range models {
4344
if err := db.AutoMigrate(model); err != nil {
@@ -175,9 +176,8 @@ func GetDB() *gorm.DB {
175176
return db
176177
}
177178

178-
// IsNotFound checks if the given error is a GORM record not found error.
179179
func IsNotFound(err error) bool {
180-
return err == gorm.ErrRecordNotFound
180+
return errors.Is(err, gorm.ErrRecordNotFound)
181181
}
182182

183183
// IsSQLiteDB checks if the given file is a valid SQLite database by reading its signature.

database/model/model.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ type Setting struct {
104104
Value string `json:"value" form:"value"`
105105
}
106106

107+
type CustomGeoResource struct {
108+
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
109+
Type string `json:"type" gorm:"not null;uniqueIndex:idx_custom_geo_type_alias;column:geo_type"`
110+
Alias string `json:"alias" gorm:"not null;uniqueIndex:idx_custom_geo_type_alias"`
111+
Url string `json:"url" gorm:"not null"`
112+
LocalPath string `json:"localPath" gorm:"column:local_path"`
113+
LastUpdatedAt int64 `json:"lastUpdatedAt" gorm:"default:0;column:last_updated_at"`
114+
LastModified string `json:"lastModified" gorm:"column:last_modified"`
115+
CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime;column:created_at"`
116+
UpdatedAt int64 `json:"updatedAt" gorm:"autoUpdateTime;column:updated_at"`
117+
}
118+
107119
// Client represents a client configuration for Xray inbounds with traffic limits and settings.
108120
type Client struct {
109121
ID string `json:"id"` // Unique client identifier

web/assets/css/custom.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/controller/api.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ type APIController struct {
1818
}
1919

2020
// NewAPIController creates a new APIController instance and initializes its routes.
21-
func NewAPIController(g *gin.RouterGroup) *APIController {
21+
func NewAPIController(g *gin.RouterGroup, customGeo service.CustomGeoService) *APIController {
2222
a := &APIController{}
23-
a.initRouter(g)
23+
a.initRouter(g, customGeo)
2424
return a
2525
}
2626

@@ -35,7 +35,7 @@ func (a *APIController) checkAPIAuth(c *gin.Context) {
3535
}
3636

3737
// initRouter sets up the API routes for inbounds, server, and other endpoints.
38-
func (a *APIController) initRouter(g *gin.RouterGroup) {
38+
func (a *APIController) initRouter(g *gin.RouterGroup, customGeo service.CustomGeoService) {
3939
// Main API group
4040
api := g.Group("/panel/api")
4141
api.Use(a.checkAPIAuth)
@@ -48,6 +48,8 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
4848
server := api.Group("/server")
4949
a.serverController = NewServerController(server)
5050

51+
NewCustomGeoController(api.Group("/custom-geo"), customGeo)
52+
5153
// Extra routes
5254
api.GET("/backuptotgbot", a.BackuptoTgbot)
5355
}

0 commit comments

Comments
 (0)