소스 검색

Vnet订阅适配+Trojan订阅

兔姬桑 4 년 전
부모
커밋
1f83af48aa

+ 62 - 37
app/Http/Controllers/Controller.php

@@ -139,69 +139,94 @@ class Controller extends BaseController {
 	 * @return string
 	 */
 	public function getUserNodeInfo($uid, $nodeId, $infoType): string {
-		$user = User::whereId($uid)->first();
-		$node = SsNode::whereId($nodeId)->first();
+		$user = User::whereId($uid)->firstOrFail();
+		$node = SsNode::whereId($nodeId)->firstOrFail();
 		$scheme = null;
 		// 获取分组名称
 		$group = $node->getLevel->name;
 		$host = $node->server?: $node->ip;
 		$data = null;
 		switch($node->type){
+			case 2:
+				// 生成v2ray scheme
+				if($infoType !== 1){
+					// 生成v2ray scheme
+					$data = $this->v2raySubUrl($node->name, $host, $node->v2_port, $user->vmess_id, $node->v2_alter_id,
+						$node->v2_net, $node->v2_type, $node->v2_host, $node->v2_path, $node->v2_tls? "tls" : "");
+				}else{
+					$data = "服务器:".$host.PHP_EOL."IPv6:".($node->ipv6?: "").PHP_EOL."端口:".$node->v2_port.PHP_EOL."加密方式:".$node->v2_method.PHP_EOL."用户ID:".$user->vmess_id.PHP_EOL."额外ID:".$node->v2_alter_id.PHP_EOL."传输协议:".$node->v2_net.PHP_EOL."伪装类型:".$node->v2_type.PHP_EOL."伪装域名:".($node->v2_host?: "").PHP_EOL."路径:".($node->v2_path?: "").PHP_EOL."TLS:".($node->v2_tls? "tls" : "").PHP_EOL;
+				}
+				break;
+			case 3:
+				if($infoType !== 1){
+					$data = $this->trojanSubUrl($user->passwd, $host, $node->port, $node->name);
+				}else{
+					$data = "备注:".$node->name.PHP_EOL."服务器:".$host.PHP_EOL."密码:".$user->passwd.PHP_EOL."端口:".$node->port.PHP_EOL;
+				}
+				break;
 			case 1:
+			case 4:
+				$protocol = $node->protocol;
+				$method = $node->method;
+				$obfs = $node->obfs;
 				if($node->single){
 					$port = $node->port;
-					$protocol = $node->protocol;
-					$method = $node->method;
-					$obfs = $node->obfs;
 					$passwd = $node->passwd;
 					$protocol_param = $user->port.':'.$user->passwd;
 				}else{
 					$port = $user->port;
-					$protocol = $user->protocol;
-					$method = $user->method;
-					$obfs = $user->obfs;
 					$passwd = $user->passwd;
 					$protocol_param = $node->protocol_param;
+					if($node->type === 1){
+						$protocol = $user->protocol;
+						$method = $user->method;
+						$obfs = $user->obfs;
+					}
 				}
 
-				if($infoType != 1){
+				if($infoType !== 1){
 					// 生成ss/ssr scheme
-					if($node->compatible){
-						$data = 'ss://'.base64url_encode($method.':'.$passwd.'@'.$host.':'.$port).'#'.$group;
-					}else{
-						$data = 'ssr://'.base64url_encode($host.':'.$port.':'.$protocol.':'.$method.':'.$obfs.':'.base64url_encode($passwd).'/?obfsparam='.base64url_encode($node->obfs_param).'&protoparam='.base64url_encode($protocol_param).'&remarks='.base64url_encode($node->name).'&group='.base64url_encode($group).'&udpport=0&uot=0');
-					}
+					$data = $node->compatible? $this->ssSubUrl($host, $port, $method, $passwd,
+						$group) : $this->ssrSubUrl($host, $port, $protocol, $method, $obfs, $passwd, $node->obfs_param,
+						$protocol_param, $node->name, $group, $node->is_udp);
 				}else{
 					// 生成文本配置信息
 					$data = "服务器:".$host.PHP_EOL."IPv6:".$node->ipv6.PHP_EOL."服务器端口:".$port.PHP_EOL."密码:".$passwd.PHP_EOL."加密:".$method.PHP_EOL.($node->compatible? '' : "协议:".$protocol.PHP_EOL."协议参数:".$protocol_param.PHP_EOL."混淆:".$obfs.PHP_EOL."混淆参数:".$node->obfs_param.PHP_EOL);
 				}
 				break;
-			case 2:
-				// 生成v2ray scheme
-				if($infoType != 1){
-					// 生成v2ray scheme
-					$data = 'vmess://'.base64url_encode(json_encode([
-							"v"    => "2",
-							"ps"   => $node->name,
-							"add"  => $host,
-							"port" => $node->v2_port,
-							"id"   => $user->vmess_id,
-							"aid"  => $node->v2_alter_id,
-							"net"  => $node->v2_net,
-							"type" => $node->v2_type,
-							"host" => $node->v2_host,
-							"path" => $node->v2_path,
-							"tls"  => $node->v2_tls? "tls" : ""
-						], JSON_PRETTY_PRINT));
-				}else{
-					$data = "服务器:".$host.PHP_EOL."IPv6:".($node->ipv6?: "").PHP_EOL."端口:".$node->v2_port.PHP_EOL."加密方式:".$node->v2_method.PHP_EOL."用户ID:".$user->vmess_id.PHP_EOL."额外ID:".$node->v2_alter_id.PHP_EOL."传输协议:".$node->v2_net.PHP_EOL."伪装类型:".$node->v2_type.PHP_EOL."伪装域名:".($node->v2_host?: "").PHP_EOL."路径:".($node->v2_path?: "").PHP_EOL."TLS:".($node->v2_tls? "tls" : "").PHP_EOL;
-				}
-				break;
-			case 3:
-				break;
 			default:
 		}
 
 		return $data;
 	}
+
+	public function v2raySubUrl($name, $host, $port, $uuid, $alter_id, $net, $type, $domain, $path, $tls): string {
+		return 'vmess://'.base64url_encode(json_encode([
+				"v"    => "2",
+				"ps"   => $name,
+				"add"  => $host,
+				"port" => $port,
+				"id"   => $uuid,
+				"aid"  => $alter_id,
+				"net"  => $net,
+				"type" => $type,
+				"host" => $domain,
+				"path" => $path,
+				"tls"  => $tls? "tls" : ""
+			], JSON_PRETTY_PRINT));
+	}
+
+	public function trojanSubUrl($password, $domain, $port, $remark): string {
+		return 'trojan://'.urlencode($password).'@'.$domain.':'.$port.'#'.urlencode($remark);
+	}
+
+	public function ssSubUrl($host, $port, $method, $passwd, $group): string {
+		return 'ss://'.base64url_encode($method.':'.$passwd.'@'.$host.':'.$port).'#'.$group;
+	}
+
+	public function ssrSubUrl(
+		$host, $port, $protocol, $method, $obfs, $passwd, $obfs_param, $protocol_param, $name, $group, $is_udp
+	): string {
+		return 'ssr://'.base64url_encode($host.':'.$port.':'.$protocol.':'.$method.':'.$obfs.':'.base64url_encode($passwd).'/?obfsparam='.base64url_encode($obfs_param).'&protoparam='.base64url_encode($protocol_param).'&remarks='.base64url_encode($name).'&group='.base64url_encode($group).'&udpport='.$is_udp.'&uot=0');
+	}
 }

+ 3 - 1
app/Http/Controllers/User/SubscribeController.php

@@ -73,7 +73,9 @@ class SubscribeController extends Controller {
 		// 获取这个账号可用节点
 		$query = SsNode::query()->whereStatus(1)->whereIsSubscribe(1)->where('level', '<=', $user->level);
 
-		if($this->subType){
+		if($this->subType === 1){
+			$query = $query->whereIn('type', [1, 4]);
+		}elseif($this->subType){
 			$query = $query->whereType($this->subType);
 		}
 

+ 1 - 1
app/Http/Controllers/UserController.php

@@ -588,7 +588,7 @@ class UserController extends Controller {
 	public function help(): \Illuminate\Http\Response {
 		//$view['articleList'] = Article::type(1)->orderByDesc('sort')->orderByDesc('id')->limit(10)->paginate(5);
 		$data = [];
-		if(SsNode::query()->whereType(1)->whereStatus(1)->exists()){
+		if(SsNode::query()->whereIn('type',[1,4])->whereStatus(1)->exists()){
 			$data[] = 'ss';
 			//array_push
 		}

+ 73 - 0
database/migrations/2020_07_18_032504_create_node_table.php

@@ -0,0 +1,73 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateNodeTable extends Migration {
+	/**
+	 * Run the migrations.
+	 *
+	 * @return void
+	 */
+	public function up() {
+		Schema::create('node', function(Blueprint $table) {
+			$table->bigIncrements('id');
+			$table->unsignedTinyInteger('type')->default(1)->comment('服务类型:1-Shadowsocks(R)、2-V2ray、3-Trojan、4-VNet');
+			$table->string('name', 128)->comment('名称');
+			$table->char('country_code', 5)->default('un')->comment('国家代码');
+			$table->string('server')->nullable()->comment('服务器域名地址');
+			$table->char('ip', 15)->nullable()->comment('服务器IPV4地址');
+			$table->ipAddress('ipv6')->nullable()->comment('服务器IPV6地址');
+			$table->string('relay_server')->nullable()->comment('中转地址');
+			$table->unsignedSmallInteger('relay_port')->nullable()->default(0)->comment('中转端口');
+			$table->unsignedTinyInteger('level')->default(0)->comment('等级:0-无等级,全部可见');
+			$table->unsignedBigInteger('speed_limit')->default(0)->comment('节点限速,为0表示不限速,单位Byte');
+			$table->unsignedSmallInteger('client_limit')->default(0)->comment('设备数限制');
+			$table->string('description')->nullable()->comment('节点简单描述');
+			$table->string('method', 32)->default('aes-256-cfb')->comment('加密方式');
+			$table->string('protocol', 64)->default('origin')->comment('协议');
+			$table->string('protocol_param', 128)->nullable()->comment('协议参数');
+			$table->string('obfs', 64)->default('plain')->comment('混淆');
+			$table->string('obfs_param')->nullable()->comment('混淆参数');
+			$table->unsignedDecimal('traffic_rate', 6)->default(1.00)->comment('流量比率');
+			$table->boolean('is_subscribe')->default(1)->comment('是否允许用户订阅该节点:0-否、1-是');
+			$table->boolean('is_ddns')->default(0)->comment('是否使用DDNS:0-否、1-是');
+			$table->boolean('is_relay')->default(0)->comment('是否中转节点:0-否、1-是');
+			$table->boolean('is_udp')->default(1)->comment('是否启用UDP:0-不启用、1-启用');
+			$table->unsignedSmallInteger('push_port')->default(0)->comment('消息推送端口');
+			$table->boolean('detection_type')->default(1)->comment('节点检测: 0-关闭、1-只检测TCP、2-只检测ICMP、3-检测全部');
+			$table->boolean('compatible')->default(0)->comment('兼容SS');
+			$table->boolean('single')->default(0)->comment('启用单端口功能:0-否、1-是');
+			$table->unsignedSmallInteger('port')->nullable()->comment('单端口的端口号或连接端口号');
+			$table->string('passwd')->nullable()->comment('单端口的连接密码');
+			$table->unsignedTinyInteger('sort')->default(0)->comment('排序值,值越大越靠前显示');
+			$table->boolean('status')->default(1)->comment('状态:0-维护、1-正常');
+			$table->unsignedSmallInteger('v2_alter_id')->default(16)->comment('V2Ray额外ID');
+			$table->unsignedSmallInteger('v2_port')->default(0)->comment('V2Ray服务端口');
+			$table->string('v2_method', 32)->default('aes-128-gcm')->comment('V2Ray加密方式');
+			$table->string('v2_net', 16)->default('tcp')->comment('V2Ray传输协议');
+			$table->string('v2_type', 32)->default('none')->comment('V2Ray伪装类型');
+			$table->string('v2_host')->comment('V2Ray伪装的域名');
+			$table->string('v2_path')->comment('V2Ray的WS/H2路径');
+			$table->boolean('v2_tls')->default(0)->comment('V2Ray后端TLS:0-未开启、1-开启');
+			$table->text('tls_provider')->nullable()->comment('V2Ray节点的TLS提供商授权信息');
+			$table->timestamps();
+			$table->index('is_subscribe', 'idx_sub');
+			$table->engine = 'InnoDB';
+			$table->charset = 'utf8mb4';
+			$table->collation = 'utf8mb4_unicode_ci';
+		});
+
+		DB::statement("ALTER TABLE `node` comment '节点信息表'");
+	}
+
+	/**
+	 * Reverse the migrations.
+	 *
+	 * @return void
+	 */
+	public function down() {
+		Schema::dropIfExists('node');
+	}
+}

+ 416 - 408
public/install.php

@@ -1,6 +1,6 @@
 <?php
 /**
- * OtakuCloud安装程序
+ *ProxyPanel安装程序
  *
  * 安装完成后建议删除此文件
  *
@@ -13,453 +13,461 @@
 define('DS', DIRECTORY_SEPARATOR);
 
 // 定义根目录
-define('ROOT_PATH', __DIR__ . DS . '..' . DS);
+define('ROOT_PATH', __DIR__.DS.'..'.DS);
 
 // 定义应用目录
-define('APP_PATH', ROOT_PATH . 'app' . DS);
+define('APP_PATH', ROOT_PATH.'app'.DS);
 
 // 安装包目录
-define('INSTALL_PATH', ROOT_PATH . 'sql' . DS);
+define('INSTALL_PATH', ROOT_PATH.'sql'.DS);
 
 // 判断文件或目录是否有写的权限
-function is_really_writable($file)
-{
-    if (DIRECTORY_SEPARATOR == '/' and @ ini_get("safe_mode") == false) {
-        return is_writable($file);
-    }
+function is_really_writable($file) {
+	if(DIRECTORY_SEPARATOR == '/' and @ ini_get("safe_mode") == false){
+		return is_writable($file);
+	}
 
-    if (!is_file($file) or ($fp = @fopen($file, "r+")) === false) {
-        return false;
-    }
+	if(!is_file($file) or ($fp = @fopen($file, "r+")) === false){
+		return false;
+	}
 
-    fclose($fp);
+	fclose($fp);
 
-    return true;
+	return true;
 }
 
 // 写配置文件
-function write_ini_file($assoc_arr, $path, $has_sections = false)
-{
-    $content = "";
-    if ($has_sections) {
-        foreach ($assoc_arr as $key => $elem) {
-            $content .= "[" . $key . "]\n";
-            foreach ($elem as $key2 => $elem2) {
-                if (is_array($elem2)) {
-                    for ($i = 0; $i < count($elem2); $i++) {
-                        $content .= $key2 . "[] = \"" . $elem2[$i] . "\"\n";
-                    }
-                } elseif ($elem2 == "")
-                    $content .= $key2 . " = \n";
-                else
-                    $content .= $key2 . " = \"" . $elem2 . "\"\n";
-            }
-        }
-    } else {
-        foreach ($assoc_arr as $key => $elem) {
-            if (is_array($elem)) {
-                for ($i = 0; $i < count($elem); $i++) {
-                    $content .= $key . "[] = \"" . $elem[$i] . "\"\n";
-                }
-            } elseif ($elem == "")
-                $content .= $key . " = \n";
-            else
-                $content .= $key . " = \"" . $elem . "\"\n";
-        }
-    }
-
-    if (!$handle = fopen($path, 'w')) {
-        return false;
-    }
-
-    if (!fwrite($handle, $content)) {
-        return false;
-    }
-
-    fclose($handle);
-
-    return true;
+function write_ini_file($assoc_arr, $path, $has_sections = false) {
+	$content = "";
+	if($has_sections){
+		foreach($assoc_arr as $key => $elem){
+			$content .= "[".$key."]\n";
+			foreach($elem as $key2 => $elem2){
+				if(is_array($elem2)){
+					for($i = 0; $i < count($elem2); $i++){
+						$content .= $key2."[] = \"".$elem2[$i]."\"\n";
+					}
+				}elseif($elem2 == ""){
+					$content .= $key2." = \n";
+				}else{
+					$content .= $key2." = \"".$elem2."\"\n";
+				}
+			}
+		}
+	}else{
+		foreach($assoc_arr as $key => $elem){
+			if(is_array($elem)){
+				for($i = 0; $i < count($elem); $i++){
+					$content .= $key."[] = \"".$elem[$i]."\"\n";
+				}
+			}elseif($elem == ""){
+				$content .= $key." = \n";
+			}else{
+				$content .= $key." = \"".$elem."\"\n";
+			}
+		}
+	}
+
+	if(!$handle = fopen($path, 'w')){
+		return false;
+	}
+
+	if(!fwrite($handle, $content)){
+		return false;
+	}
+
+	fclose($handle);
+
+	return true;
 }
 
 $sitename = "OtakuCloud";
 
 // 检测目录是否存在
 $checkDirs = [
-    'vendor',
+	'vendor',
 ];
 
 // 错误信息
 $errInfo = '';
 
 // 数据库配置文件
-$ConfigFile = ROOT_PATH . '.env';
+$ConfigFile = ROOT_PATH.'.env';
 
 // 数据库标准配置文件
-$exampleConfigFile = ROOT_PATH . '.env.example';
+$exampleConfigFile = ROOT_PATH.'.env.example';
 
 // 锁定的文件
-$lockFile = ROOT_PATH . '.env';
-if (is_file($lockFile)) {
-    $errInfo = "当前已经安装{$sitename},如果需要重新安装,请手动移除.env文件";
-} elseif (version_compare(PHP_VERSION, '7.1.3', '<')) {
-    $errInfo = "当前PHP版本(" . PHP_VERSION . ")过低,请使用PHP7.1.3及以上版本";
-} elseif (!is_file($exampleConfigFile)) {
-    $errInfo = "缺失标准配置文件.env.example";
-} elseif (!extension_loaded("PDO")) {
-    $errInfo = "当前PHP环境未启用PDO组件,无法进行安装";
-} elseif (!is_really_writable(ROOT_PATH)) {
-    $open_basedir = ini_get('open_basedir');
-    if ($open_basedir) {
-        $dirArr = explode(PATH_SEPARATOR, $open_basedir);
-        if ($dirArr && in_array(__DIR__, $dirArr)) {
-            $errInfo = '当前服务器因配置了open_basedir,导致无法读取应用根目录';
-        }
-    }
-
-    if (!$errInfo) {
-        $errInfo = '权限不足,无法写入配置文件.env';
-    }
-} else {
-    $dirArr = [];
-    foreach ($checkDirs as $k => $v) {
-        if (!is_dir(ROOT_PATH . $v)) {
-            $errInfo = '请先在' . $sitename . '根目录下执行 php composer.phar install 安装依赖';
-            break;
-        }
-    }
+$lockFile = ROOT_PATH.'.env';
+if(is_file($lockFile)){
+	$errInfo = "当前已经安装{$sitename},如果需要重新安装,请手动移除.env文件";
+}elseif(version_compare(PHP_VERSION, '7.1.3', '<')){
+	$errInfo = "当前PHP版本(".PHP_VERSION.")过低,请使用PHP7.1.3及以上版本";
+}elseif(!is_file($exampleConfigFile)){
+	$errInfo = "缺失标准配置文件.env.example";
+}elseif(!extension_loaded("PDO")){
+	$errInfo = "当前PHP环境未启用PDO组件,无法进行安装";
+}elseif(!is_really_writable(ROOT_PATH)){
+	$open_basedir = ini_get('open_basedir');
+	if($open_basedir){
+		$dirArr = explode(PATH_SEPARATOR, $open_basedir);
+		if($dirArr && in_array(__DIR__, $dirArr)){
+			$errInfo = '当前服务器因配置了open_basedir,导致无法读取应用根目录';
+		}
+	}
+
+	if(!$errInfo){
+		$errInfo = '权限不足,无法写入配置文件.env';
+	}
+}else{
+	$dirArr = [];
+	foreach($checkDirs as $k => $v){
+		if(!is_dir(ROOT_PATH.$v)){
+			$errInfo = '请先在'.$sitename.'根目录下执行 php composer.phar install 安装依赖';
+			break;
+		}
+	}
 }
 
 // 当前是POST请求
-if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') {
-    if ($errInfo) {
-        echo $errInfo;
-        exit;
-    }
-
-    $err = '';
-    $APP_KEY = md5(time() . mt_rand(1, 1000000));
-    $DB_HOST = isset($_POST['mysqlHost']) ? $_POST['mysqlHost'] : '127.0.0.1';
-    $DB_PORT = isset($_POST['mysqlHostport']) ? $_POST['mysqlHostport'] : 3306;
-    $hostArr = explode(':', $DB_HOST);
-    if (count($hostArr) > 1) {
-        $DB_HOST = $hostArr[0];
-        $DB_PORT = $hostArr[1];
-    }
-    $DB_USERNAME = isset($_POST['mysqlUsername']) ? $_POST['mysqlUsername'] : 'root';
-    $DB_PASSWORD = isset($_POST['mysqlPassword']) ? $_POST['mysqlPassword'] : '';
-    $DB_DATABASE = isset($_POST['mysqlDatabase']) ? $_POST['mysqlDatabase'] : 'ssrpanel';
-//    $adminUsername = isset($_POST['adminUsername']) ? $_POST['adminUsername'] : 'admin';
-//    $adminPassword = isset($_POST['adminPassword']) ? $_POST['adminPassword'] : 'admin';
-//    $adminPasswordConfirmation = isset($_POST['adminPasswordConfirmation']) ? $_POST['adminPasswordConfirmation'] : 'admin';
-//    $adminEmail = isset($_POST['adminEmail']) ? $_POST['adminEmail'] : 'admin@admin.com';
-//    if ($adminPassword !== $adminPasswordConfirmation) {
-//        echo "两次输入的密码不一致";
-//        exit;
-//    } else if (!preg_match("/^\w+$/", $adminUsername)) {
-//        echo "用户名只能输入字母、数字、下划线";
-//        exit;
-//    } else if (!preg_match("/^[\S]+$/", $adminPassword)) {
-//        echo "密码不能包含空格";
-//        exit;
-//    } else if (strlen($adminUsername) < 3 || strlen($adminUsername) > 12) {
-//        echo "用户名请输入3~12位字符";
-//        exit;
-//    } else if (strlen($adminPassword) < 6 || strlen($adminPassword) > 16 || stripos($adminPassword, ' ') !== false) {
-//        echo "密码请输入6~16位字符,不能包含空格";
-//        exit;
-//    }
-    try {
-        // 检测能否读取安装文件
-        $sql = @file_get_contents(INSTALL_PATH . 'db.sql');
-        if (!$sql) {
-            throw new Exception("无法读取所需的sql/db.sql,请检查是否有读权限");
-        }
-
-        $pdo = new PDO("mysql:host={$DB_HOST};port={$DB_PORT}", $DB_USERNAME, $DB_PASSWORD, [
-            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
-            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
-        ]);
-
-        // 检测是否支持innodb存储引擎
-        $pdoStatement = $pdo->query("SHOW VARIABLES LIKE 'innodb_version'");
-        $result = $pdoStatement->fetch();
-        if (!$result) {
-            throw new Exception("当前数据库不支持innodb存储引擎,请开启后再重新尝试安装");
-        }
-
-        $pdo->query("CREATE DATABASE IF NOT EXISTS `{$DB_DATABASE}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
-        $pdo->query("USE `{$DB_DATABASE}`");
-        $pdo->exec($sql);
-
-        $config = @file_get_contents($exampleConfigFile);
-        if (!$config) {
-            throw new Exception("无法写入读取配置.env.example文件,请检查是否有读权限");
-        }
-
-        $callback = function ($matches) use ($APP_KEY, $DB_HOST, $DB_PORT, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE) {
-            $field = $matches[1];
-            $replace = ${"{$field}"};
-            return "{$matches[1]}={$replace}" . PHP_EOL;
-        };
-
-        $config = preg_replace_callback("/(APP_KEY|DB_HOST|DB_DATABASE|DB_USERNAME|DB_PASSWORD|DB_PORT)=(.*)(\s+)/", $callback, $config);
-
-        // 检测能否成功写入数据库配置
-        $result = @file_put_contents($ConfigFile, $config);
-        if (!$result) {
-            throw new Exception("无法写入数据库信息到.env文件,请检查是否有写权限");
-        }
-
-        echo "success";
-    } catch (PDOException $e) {
-        $err = $e->getMessage();
-    } catch (Exception $e) {
-        $err = $e->getMessage();
-    }
-
-    echo $err;
-    exit;
+if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
+	if($errInfo){
+		echo $errInfo;
+		exit;
+	}
+
+	$err = '';
+	$APP_KEY = md5(time().mt_rand(1, 1000000));
+	$DB_HOST = isset($_POST['mysqlHost'])? $_POST['mysqlHost'] : '127.0.0.1';
+	$DB_PORT = isset($_POST['mysqlHostport'])? $_POST['mysqlHostport'] : 3306;
+	$hostArr = explode(':', $DB_HOST);
+	if(count($hostArr) > 1){
+		$DB_HOST = $hostArr[0];
+		$DB_PORT = $hostArr[1];
+	}
+	$DB_USERNAME = isset($_POST['mysqlUsername'])? $_POST['mysqlUsername'] : 'root';
+	$DB_PASSWORD = isset($_POST['mysqlPassword'])? $_POST['mysqlPassword'] : '';
+	$DB_DATABASE = isset($_POST['mysqlDatabase'])? $_POST['mysqlDatabase'] : 'proxypanel';
+	//    $adminUsername = isset($_POST['adminUsername']) ? $_POST['adminUsername'] : 'admin';
+	//    $adminPassword = isset($_POST['adminPassword']) ? $_POST['adminPassword'] : 'admin';
+	//    $adminPasswordConfirmation = isset($_POST['adminPasswordConfirmation']) ? $_POST['adminPasswordConfirmation'] : 'admin';
+	//    $adminEmail = isset($_POST['adminEmail']) ? $_POST['adminEmail'] : 'admin@admin.com';
+	//    if ($adminPassword !== $adminPasswordConfirmation) {
+	//        echo "两次输入的密码不一致";
+	//        exit;
+	//    } else if (!preg_match("/^\w+$/", $adminUsername)) {
+	//        echo "用户名只能输入字母、数字、下划线";
+	//        exit;
+	//    } else if (!preg_match("/^[\S]+$/", $adminPassword)) {
+	//        echo "密码不能包含空格";
+	//        exit;
+	//    } else if (strlen($adminUsername) < 3 || strlen($adminUsername) > 12) {
+	//        echo "用户名请输入3~12位字符";
+	//        exit;
+	//    } else if (strlen($adminPassword) < 6 || strlen($adminPassword) > 16 || stripos($adminPassword, ' ') !== false) {
+	//        echo "密码请输入6~16位字符,不能包含空格";
+	//        exit;
+	//    }
+	try{
+		// 检测能否读取安装文件
+		$sql = @file_get_contents(INSTALL_PATH.'db.sql');
+		if(!$sql){
+			throw new Exception("无法读取所需的sql/db.sql,请检查是否有读权限");
+		}
+
+		$pdo = new PDO("mysql:host={$DB_HOST};port={$DB_PORT}", $DB_USERNAME, $DB_PASSWORD, [
+			PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
+			PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
+		]);
+
+		// 检测是否支持innodb存储引擎
+		$pdoStatement = $pdo->query("SHOW VARIABLES LIKE 'innodb_version'");
+		$result = $pdoStatement->fetch();
+		if(!$result){
+			throw new Exception("当前数据库不支持innodb存储引擎,请开启后再重新尝试安装");
+		}
+
+		$pdo->query("CREATE DATABASE IF NOT EXISTS `{$DB_DATABASE}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
+		$pdo->query("USE `{$DB_DATABASE}`");
+		$pdo->exec($sql);
+
+		$config = @file_get_contents($exampleConfigFile);
+		if(!$config){
+			throw new Exception("无法写入读取配置.env.example文件,请检查是否有读权限");
+		}
+
+		$callback = function($matches) use ($APP_KEY, $DB_HOST, $DB_PORT, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE) {
+			$field = $matches[1];
+			$replace = ${"{$field}"};
+			return "{$matches[1]}={$replace}".PHP_EOL;
+		};
+
+		$config = preg_replace_callback("/(APP_KEY|DB_HOST|DB_DATABASE|DB_USERNAME|DB_PASSWORD|DB_PORT)=(.*)(\s+)/",
+			$callback, $config);
+
+		// 检测能否成功写入数据库配置
+		$result = @file_put_contents($ConfigFile, $config);
+		if(!$result){
+			throw new Exception("无法写入数据库信息到.env文件,请检查是否有写权限");
+		}
+
+		echo "success";
+	}catch(PDOException $e){
+		$err = $e->getMessage();
+	}catch(Exception $e){
+		$err = $e->getMessage();
+	}
+
+	echo $err;
+	exit;
 }
 ?>
 <!doctype html>
 <html>
 <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <title>安装<?php echo $sitename; ?></title>
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
-    <meta name="renderer" content="webkit">
-
-    <style type="text/css">
-        body {
-            background: #5c97bd;
-            margin: 0;
-            padding: 0;
-            line-height: 1.5;
-        }
-
-        body, input, button {
-            font-family: 'Open Sans', sans-serif;
-            font-size: 16px;
-            color: #fff;
-        }
-
-        .container {
-            max-width: 515px;
-            margin: 0 auto;
-            padding: 20px;
-            text-align: center;
-        }
-
-        a {
-            color: #fff7d0;
-            text-decoration: none;
-        }
-
-        a:hover {
-            text-decoration: underline;
-        }
-
-        h1 {
-            margin-top: 0;
-            margin-bottom: 10px;
-        }
-
-        h2 {
-            font-size: 28px;
-            font-weight: normal;
-            color: #fff;
-            margin-bottom: 0;
-        }
-
-        form {
-            margin-top: 40px;
-        }
-
-        .form-group {
-            margin-bottom: 20px;
-        }
-
-        .form-group .form-field:first-child input {
-            border-top-left-radius: 4px;
-            border-top-right-radius: 4px;
-        }
-
-        .form-group .form-field:last-child input {
-            border-bottom-left-radius: 4px;
-            border-bottom-right-radius: 4px;
-        }
-
-        .form-field input {
-            background: #6ba3c8;
-            margin: 0 0 1px;
-            border: 2px solid transparent;
-            transition: background 0.2s, border-color 0.2s, color 0.2s;
-            width: 100%;
-            padding: 15px 15px 15px 180px;
-            box-sizing: border-box;
-        }
-
-        .form-field input:focus {
-            border-color: #e8f6ff;
-            outline: none;
-        }
-
-        .form-field label {
-            float: left;
-            width: 160px;
-            text-align: right;
-            margin-right: -160px;
-            position: relative;
-            margin-top: 18px;
-            font-size: 14px;
-            pointer-events: none;
-            opacity: 0.7;
-        }
-
-        button, .btn {
-            background: #fff;
-            color: #6ba3ca;
-            border: 0;
-            font-weight: bold;
-            border-radius: 4px;
-            cursor: pointer;
-            padding: 15px 30px;
-            -webkit-appearance: none;
-        }
-
-        button[disabled] {
-            opacity: 0.5;
-        }
-
-        #error, .error, #success, .success {
-            background: #d66c6c;
-            color: #fff;
-            padding: 15px 20px;
-            border-radius: 4px;
-            margin-bottom: 20px;
-        }
-
-        #success {
-            background: #3C5675;
-        }
-
-        #error a, .error a {
-            color: white;
-            text-decoration: underline;
-        }
-    </style>
+	<meta charset="utf-8">
+	<meta http-equiv="X-UA-Compatible" content="IE=edge">
+	<title>安装<?php
+		echo $sitename; ?></title>
+	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
+	<meta name="renderer" content="webkit">
+
+	<style type="text/css">
+		body {
+			background: #5c97bd;
+			margin: 0;
+			padding: 0;
+			line-height: 1.5;
+		}
+
+		body, input, button {
+			font-family: 'Open Sans', sans-serif;
+			font-size: 16px;
+			color: #fff;
+		}
+
+		.container {
+			max-width: 515px;
+			margin: 0 auto;
+			padding: 20px;
+			text-align: center;
+		}
+
+		a {
+			color: #fff7d0;
+			text-decoration: none;
+		}
+
+		a:hover {
+			text-decoration: underline;
+		}
+
+		h1 {
+			margin-top: 0;
+			margin-bottom: 10px;
+		}
+
+		h2 {
+			font-size: 28px;
+			font-weight: normal;
+			color: #fff;
+			margin-bottom: 0;
+		}
+
+		form {
+			margin-top: 40px;
+		}
+
+		.form-group {
+			margin-bottom: 20px;
+		}
+
+		.form-group .form-field:first-child input {
+			border-top-left-radius: 4px;
+			border-top-right-radius: 4px;
+		}
+
+		.form-group .form-field:last-child input {
+			border-bottom-left-radius: 4px;
+			border-bottom-right-radius: 4px;
+		}
+
+		.form-field input {
+			background: #6ba3c8;
+			margin: 0 0 1px;
+			border: 2px solid transparent;
+			transition: background 0.2s, border-color 0.2s, color 0.2s;
+			width: 100%;
+			padding: 15px 15px 15px 180px;
+			box-sizing: border-box;
+		}
+
+		.form-field input:focus {
+			border-color: #e8f6ff;
+			outline: none;
+		}
+
+		.form-field label {
+			float: left;
+			width: 160px;
+			text-align: right;
+			margin-right: -160px;
+			position: relative;
+			margin-top: 18px;
+			font-size: 14px;
+			pointer-events: none;
+			opacity: 0.7;
+		}
+
+		button, .btn {
+			background: #fff;
+			color: #6ba3ca;
+			border: 0;
+			font-weight: bold;
+			border-radius: 4px;
+			cursor: pointer;
+			padding: 15px 30px;
+			-webkit-appearance: none;
+		}
+
+		button[disabled] {
+			opacity: 0.5;
+		}
+
+		#error, .error, #success, .success {
+			background: #d66c6c;
+			color: #fff;
+			padding: 15px 20px;
+			border-radius: 4px;
+			margin-bottom: 20px;
+		}
+
+		#success {
+			background: #3C5675;
+		}
+
+		#error a, .error a {
+			color: white;
+			text-decoration: underline;
+		}
+	</style>
 </head>
 
 <body>
 <div class="container">
-    <h2>安装 <?php echo $sitename; ?></h2>
-    <div>
-        <form method="post">
-            <?php if ($errInfo): ?>
-                <div class="error">
-                    <?php echo $errInfo; ?>
-                </div>
-            <?php endif; ?>
-            <div id="error" style="display:none"></div>
-            <div id="success" style="display:none"></div>
-
-            <div class="form-group">
-                <div class="form-field">
-                    <label>MySQL 数据库地址</label>
-                    <input type="text" name="mysqlHost" value="127.0.0.1" required="">
-                </div>
-
-                <div class="form-field">
-                    <label>MySQL 数据库名</label>
-                    <input type="text" name="mysqlDatabase" value="ssrpanel" required="">
-                </div>
-
-                <div class="form-field">
-                    <label>MySQL 用户名</label>
-                    <input type="text" name="mysqlUsername" value="ssrpanel" required="">
-                </div>
-
-                <div class="form-field">
-                    <label>MySQL 密码</label>
-                    <input type="password" name="mysqlPassword">
-                </div>
-
-                <div class="form-field">
-                    <label>MySQL 端口号</label>
-                    <input type="number" name="mysqlHostport" value="3306">
-                </div>
-            </div>
-
-            <!--            <div class="form-group">-->
-            <!--                <div class="form-field">-->
-            <!--                    <label>管理者用户名</label>-->
-            <!--                    <input name="adminUsername" value="admin" required=""/>-->
-            <!--                </div>-->
-            <!---->
-            <!--                <div class="form-field">-->
-            <!--                    <label>管理者Email</label>-->
-            <!--                    <input name="adminEmail" value="admin@admin.com" required="">-->
-            <!--                </div>-->
-            <!---->
-            <!--                <div class="form-field">-->
-            <!--                    <label>管理者密码</label>-->
-            <!--                    <input type="password" name="adminPassword" required="">-->
-            <!--                </div>-->
-            <!---->
-            <!--                <div class="form-field">-->
-            <!--                    <label>重复密码</label>-->
-            <!--                    <input type="password" name="adminPasswordConfirmation" required="">-->
-            <!--                </div>-->
-            <!--            </div>-->
-
-            <div class="form-buttons">
-                <button type="submit" <?php echo $errInfo ? 'disabled' : '' ?>>点击安装</button>
-            </div>
-        </form>
-
-        <!-- jQuery -->
-        <script src="//cdn.staticfile.org/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>
-
-        <script type="text/javascript">
-            $(function () {
-
-                $('form').on('submit', function (e) {
-                    e.preventDefault();
-
-                    var $button = $(this).find('button')
-                        .text('安装中...')
-                        .prop('disabled', true);
-
-                    $.post('', $(this).serialize())
-                        .done(function (ret) {
-                            if (ret === 'success') {
-                                $('#error').hide();
-                                $("#success").text("<?php echo $sitename; ?>安装成功,请使用默认用户名admin、密码123456登录,并尽快修改密码并重置订阅地址。").show();
-                                $('<a class="btn" href="./">进入SSRPanel</a>').insertAfter($button);
-                                $button.remove();
-                                localStorage.setItem("fastep", "installed");
-                            } else {
-                                $('#error').show().text(ret);
-                                $button.prop('disabled', false).text('点击安装');
-                                $("html,body").animate({
-                                    scrollTop: 0
-                                }, 500);
-                            }
-                        })
-                        .fail(function (data) {
-                            $('#error').show().text('发生错误:\n\n' + data.responseText);
-                            $button.prop('disabled', false).text('点击安装');
-                            $("html,body").animate({
-                                scrollTop: 0
-                            }, 500);
-                        });
-
-                    return false;
-                });
-            });
-        </script>
-    </div>
+	<h2>安装 <?php
+		echo $sitename; ?></h2>
+	<div>
+		<form method="post">
+			<?php
+			if($errInfo): ?>
+				<div class="error">
+					<?php
+					echo $errInfo; ?>
+				</div>
+			<?php
+			endif; ?>
+			<div id="error" style="display:none"></div>
+			<div id="success" style="display:none"></div>
+
+			<div class="form-group">
+				<div class="form-field">
+					<label>MySQL 数据库地址</label>
+					<input type="text" name="mysqlHost" value="127.0.0.1" required="">
+				</div>
+
+				<div class="form-field">
+					<label>MySQL 数据库名</label>
+					<input type="text" name="mysqlDatabase" value="proxypanel" required="">
+				</div>
+
+				<div class="form-field">
+					<label>MySQL 用户名</label>
+					<input type="text" name="mysqlUsername" value="proxypanel" required="">
+				</div>
+
+				<div class="form-field">
+					<label>MySQL 密码</label>
+					<input type="password" name="mysqlPassword">
+				</div>
+
+				<div class="form-field">
+					<label>MySQL 端口号</label>
+					<input type="number" name="mysqlHostport" value="3306">
+				</div>
+			</div>
+
+			<!--            <div class="form-group">-->
+			<!--                <div class="form-field">-->
+			<!--                    <label>管理者用户名</label>-->
+			<!--                    <input name="adminUsername" value="admin" required=""/>-->
+			<!--                </div>-->
+			<!---->
+			<!--                <div class="form-field">-->
+			<!--                    <label>管理者Email</label>-->
+			<!--                    <input name="adminEmail" value="admin@admin.com" required="">-->
+			<!--                </div>-->
+			<!---->
+			<!--                <div class="form-field">-->
+			<!--                    <label>管理者密码</label>-->
+			<!--                    <input type="password" name="adminPassword" required="">-->
+			<!--                </div>-->
+			<!---->
+			<!--                <div class="form-field">-->
+			<!--                    <label>重复密码</label>-->
+			<!--                    <input type="password" name="adminPasswordConfirmation" required="">-->
+			<!--                </div>-->
+			<!--            </div>-->
+
+			<div class="form-buttons">
+				<button type="submit" <?php
+				echo $errInfo? 'disabled' : '' ?>>点击安装
+				</button>
+			</div>
+		</form>
+
+		<!-- jQuery -->
+		<script src="//cdn.staticfile.org/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>
+
+		<script type="text/javascript">
+			$(function () {
+
+				$('form').on('submit', function (e) {
+					e.preventDefault();
+
+					var $button = $(this).find('button')
+						.text('安装中...')
+						.prop('disabled', true);
+
+					$.post('', $(this).serialize())
+						.done(function (ret) {
+							if (ret === 'success') {
+								$('#error').hide();
+								$("#success").text("<?php echo $sitename; ?>安装成功,请使用默认用户名test@test.com、密码123456登录,并尽快修改密码并重置订阅地址。").show();
+								$('<a class="btn" href="./">进入ProxyPanel</a>').insertAfter($button);
+								$button.remove();
+								localStorage.setItem("fastep", "installed");
+							} else {
+								$('#error').show().text(ret);
+								$button.prop('disabled', false).text('点击安装');
+								$("html,body").animate({
+									scrollTop: 0
+								}, 500);
+							}
+						})
+						.fail(function (data) {
+							$('#error').show().text('发生错误:\n\n' + data.responseText);
+							$button.prop('disabled', false).text('点击安装');
+							$("html,body").animate({
+								scrollTop: 0
+							}, 500);
+						});
+
+					return false;
+				});
+			});
+		</script>
+	</div>
 </div>
 </body>
 </html>

+ 11 - 1
resources/views/admin/node/nodeInfo.blade.php

@@ -139,7 +139,7 @@
 											<li class="list-inline-item">
 												<div class="radio-custom radio-primary">
 													<input type="radio" id="shadowsocks" name="type" value="1" checked>
-													<label for="shadowsocks">Shadowsocks(R) | VNET</label>
+													<label for="shadowsocks">Shadowsocks(R)</label>
 												</div>
 											</li>
 											<li class="list-inline-item">
@@ -154,6 +154,12 @@
 													<label for="trojan">Trojan</label>
 												</div>
 											</li>
+											<li class="list-inline-item">
+												<div class="radio-custom radio-primary">
+													<input type="radio" id="vnet" name="type" value="4" checked>
+													<label for="vnet">VNET</label>
+												</div>
+											</li>
 										</ul>
 									</div>
 									<hr/>
@@ -469,6 +475,7 @@
 				$('.obfs_param').hide();
 			}
 		});
+
 		// ajax同步提交
 		function Submit() {
 			$.ajax({
@@ -596,6 +603,9 @@
 				case 3:
 					$trojan_setting.show();
 					break;
+				case 4:
+					$ssr_setting.show();
+					break;
 				default:
 			}
 		});

+ 7 - 7
sql/db.sql

@@ -26,12 +26,12 @@
 CREATE TABLE `ss_node`
 (
     `id`             INT(10) UNSIGNED     NOT NULL AUTO_INCREMENT,
-    `type`           TINYINT(1) UNSIGNED  NOT NULL DEFAULT '1' COMMENT '服务类型:1-ShadowsocksR、2-V2ray',
+    `type`           TINYINT(1) UNSIGNED  NOT NULL DEFAULT '1' COMMENT '服务类型:1-Shadowsocks(R)、2-V2ray、3-Trojan、4-VNet',
     `name`           VARCHAR(128)         NOT NULL DEFAULT '' COMMENT '名称',
     `country_code`   CHAR(5)              NOT NULL DEFAULT 'un' COMMENT '国家代码',
     `server`         VARCHAR(255)         NULL     DEFAULT NULL COMMENT '服务器域名地址',
     `ip`             CHAR(15)             NULL     DEFAULT NULL COMMENT '服务器IPV4地址',
-    `ipv6`           VARCHAR(128)         NULL     DEFAULT NULL COMMENT '服务器IPV6地址',
+    `ipv6`           VARCHAR(45)          NULL     DEFAULT NULL COMMENT '服务器IPV6地址',
     `relay_server`   VARCHAR(255)         NULL     DEFAULT NULL COMMENT '中转地址',
     `relay_port`     SMALLINT(5) UNSIGNED NULL     DEFAULT 0 COMMENT '中转端口',
     `level`          TINYINT(3) UNSIGNED  NOT NULL DEFAULT '0' COMMENT '等级:0-无等级,全部可见',
@@ -63,7 +63,7 @@ CREATE TABLE `ss_node`
     `v2_type`        VARCHAR(32)          NOT NULL DEFAULT 'none' COMMENT 'V2Ray伪装类型',
     `v2_host`        VARCHAR(255)         NOT NULL DEFAULT '' COMMENT 'V2Ray伪装的域名',
     `v2_path`        VARCHAR(255)         NOT NULL DEFAULT '' COMMENT 'V2Ray的WS/H2路径',
-    `v2_tls`         BIT                  NOT NULL DEFAULT 0 COMMENT 'V2Ray后端TLS:0-未开启、1-开启',
+    `v2_tls`         BIT                  NOT NULL DEFAULT 0 COMMENT 'V2Ray连接TLS:0-未开启、1-开启',
     `tls_provider`   TEXT                 NULL     DEFAULT NULL COMMENT 'V2Ray节点的TLS提供商授权信息',
     `created_at`     DATETIME             NOT NULL,
     `updated_at`     DATETIME             NOT NULL,
@@ -141,12 +141,12 @@ CREATE TABLE `user`
     `password`        VARCHAR(64)          NOT NULL DEFAULT '' COMMENT '密码',
     `port`            SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT '代理端口',
     `passwd`          VARCHAR(16)          NOT NULL DEFAULT '' COMMENT '代理密码',
-    `vmess_id`        VARCHAR(64)          NOT NULL DEFAULT '',
+    `vmess_id`        CHAR(36)             NOT NULL DEFAULT '',
     `transfer_enable` BIGINT(20) UNSIGNED  NOT NULL DEFAULT '1099511627776' COMMENT '可用流量,单位字节,默认1TiB',
     `u`               BIGINT(20) UNSIGNED  NOT NULL DEFAULT '0' COMMENT '已上传流量,单位字节',
     `d`               BIGINT(20) UNSIGNED  NOT NULL DEFAULT '0' COMMENT '已下载流量,单位字节',
     `t`               INT(10) UNSIGNED     NOT NULL DEFAULT '0' COMMENT '最后使用时间',
-    `ip`              CHAR(128)                     DEFAULT NULL COMMENT '最后连接IP',
+    `ip`              CHAR(15)                     DEFAULT NULL COMMENT '最后连接IP',
     `enable`          TINYINT(1)           NOT NULL DEFAULT 1 COMMENT '代理状态',
     `method`          VARCHAR(30)          NOT NULL DEFAULT 'aes-256-cfb' COMMENT '加密方式',
     `protocol`        VARCHAR(30)          NOT NULL DEFAULT 'origin' COMMENT '协议',
@@ -976,7 +976,7 @@ CREATE TABLE `user_subscribe_log`
 (
     `id`             INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
     `sid`            INT(10) UNSIGNED DEFAULT NULL COMMENT '对应user_subscribe的id',
-    `request_ip`     CHAR(128)        DEFAULT NULL COMMENT '请求IP',
+    `request_ip`     CHAR(45)        DEFAULT NULL COMMENT '请求IP',
     `request_time`   DATETIME         DEFAULT NULL COMMENT '请求时间',
     `request_header` TEXT COMMENT '请求头部信息',
     PRIMARY KEY (`id`),
@@ -1210,7 +1210,7 @@ CREATE TABLE `user_login_log`
 (
     `id`         INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
     `user_id`    INT(10) UNSIGNED NOT NULL DEFAULT '0',
-    `ip`         VARCHAR(128)     NOT NULL,
+    `ip`         VARCHAR(45)     NOT NULL,
     `country`    VARCHAR(128)     NOT NULL,
     `province`   VARCHAR(128)     NOT NULL,
     `city`       VARCHAR(128)     NOT NULL,

+ 1 - 2
update.sh

@@ -5,6 +5,5 @@ git pull
 php composer.phar install
 php artisan key:generate
 php artisan view:clear
-php artisan route:cache
-php artisan config:cache
+php artisan optimize
 chown -R www:www ./