|
|
@@ -0,0 +1,387 @@
|
|
|
+#!/bin/bash
|
|
|
+# =====================================================
|
|
|
+# 一键开新区脚本 — 生成独立区服目录
|
|
|
+# 用法: ./create_zone.sh <区号> [选项]
|
|
|
+#
|
|
|
+# 生成目录结构:
|
|
|
+# dev/server<N>/
|
|
|
+# ├── _launch_server.xml # 该区独立配置
|
|
|
+# ├── start.sh # 启动
|
|
|
+# ├── stop.sh # 停止
|
|
|
+# ├── status.sh # 状态
|
|
|
+# └── restart.sh # 重启
|
|
|
+# =====================================================
|
|
|
+
|
|
|
+set -e
|
|
|
+
|
|
|
+# ======================== 默认配置 ========================
|
|
|
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
+BASE_OUTPUT="/data/CzServer/_output.server"
|
|
|
+DLL="$BASE_OUTPUT/OpenCards.Server.DotNetCore.dll"
|
|
|
+
|
|
|
+# 数据库密码(从现有配置读取)
|
|
|
+REDIS_PASSWORD="tmKjD1ENs3HfZ7adzLJO!"
|
|
|
+MYSQL_CONN="server=127.0.0.1;User ID=root;Password=CmASfW98lOKbFieqEQox;database=orm"
|
|
|
+NAMESERVER_ENDPOINT="127.0.0.1:17000"
|
|
|
+FIGHT_POST_URL="http://127.0.0.1:8088/fight/reqstartbattle"
|
|
|
+
|
|
|
+# 服务器公网IP
|
|
|
+SERVER_PUBLIC_IP="${SERVER_PUBLIC_IP:-127.0.0.1}"
|
|
|
+
|
|
|
+# ======================== 颜色 ========================
|
|
|
+RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
|
|
+log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
|
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
|
+log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
+log_step() { echo -e "${CYAN}[STEP]${NC} $1"; }
|
|
|
+
|
|
|
+# ======================== 参数 ========================
|
|
|
+ZONE_ID=""
|
|
|
+ZONE_NAME=""
|
|
|
+CONNECTOR_PORT=""
|
|
|
+RPC_PORT=""
|
|
|
+REDIS_DB=""
|
|
|
+SERVER_ID=""
|
|
|
+REALM_ID="1"
|
|
|
+
|
|
|
+while [[ $# -gt 0 ]]; do
|
|
|
+ case "$1" in
|
|
|
+ --port) CONNECTOR_PORT="$2"; shift 2 ;;
|
|
|
+ --rpc-port) RPC_PORT="$2"; shift 2 ;;
|
|
|
+ --name) ZONE_NAME="$2"; shift 2 ;;
|
|
|
+ --ip) SERVER_PUBLIC_IP="$2"; shift 2 ;;
|
|
|
+ --redis-db) REDIS_DB="$2"; shift 2 ;;
|
|
|
+ --realm) REALM_ID="$2"; shift 2 ;;
|
|
|
+ --nameserver) NAMESERVER_ENDPOINT="$2"; shift 2 ;;
|
|
|
+ -h|--help)
|
|
|
+ echo "用法: $0 <区号> [选项]"
|
|
|
+ echo ""
|
|
|
+ echo "参数:"
|
|
|
+ echo " 区号 第几区 (1, 2, 3...)"
|
|
|
+ echo ""
|
|
|
+ echo "选项:"
|
|
|
+ echo " --port <端口> 客户端连接端口 (默认: 19820+区号)"
|
|
|
+ echo " --rpc-port <端口> RPC端口 (默认: rpc=17019+区号)"
|
|
|
+ echo " --name <名称> 区服显示名称 (默认: 测试服N区)"
|
|
|
+ echo " --ip <IP地址> 服务器公网IP (用于serverlist)"
|
|
|
+ echo " --redis-db <编号> Redis DB (默认: 同区号)"
|
|
|
+ echo " --realm <ID> 大区ID (默认: 1)"
|
|
|
+ echo " --nameserver <地址> NameServer地址 (默认: 127.0.0.1:17000)"
|
|
|
+ echo ""
|
|
|
+ echo "示例:"
|
|
|
+ echo " $0 1 # 创建1区 (端口19821)"
|
|
|
+ echo " $0 2 # 创建2区 (端口19822)"
|
|
|
+ echo " $0 3 --port 19823 --name 正式3区"
|
|
|
+ exit 0
|
|
|
+ ;;
|
|
|
+ *) ZONE_ID="$1"; shift ;;
|
|
|
+ esac
|
|
|
+done
|
|
|
+
|
|
|
+if [ -z "$ZONE_ID" ]; then
|
|
|
+ log_error "请指定区号,如: $0 2"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+# 自动计算默认值
|
|
|
+SERVER_ID="${ZONE_ID}"
|
|
|
+REDIS_DB="${REDIS_DB:-${ZONE_ID}}"
|
|
|
+CONNECTOR_PORT="${CONNECTOR_PORT:-$((19820 + ZONE_ID))}"
|
|
|
+RPC_PORT="${RPC_PORT:-$((17019 + ZONE_ID))}"
|
|
|
+ZONE_NAME="${ZONE_NAME:-测试服${ZONE_ID}区}"
|
|
|
+
|
|
|
+# ======================== 预检查 ========================
|
|
|
+log_step "检查环境..."
|
|
|
+
|
|
|
+ZONE_DIR="${SCRIPT_DIR}/server${ZONE_ID}"
|
|
|
+GAME_NODE="GameNode${ZONE_ID}"
|
|
|
+
|
|
|
+if [ -d "$ZONE_DIR" ]; then
|
|
|
+ log_warn "目录 ${ZONE_DIR} 已存在"
|
|
|
+ read -p "是否覆盖? (y/N): " confirm
|
|
|
+ if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
|
|
+ log_info "已取消"
|
|
|
+ exit 0
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+check_port() {
|
|
|
+ local port=$1
|
|
|
+ (ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null) | grep -q ":${port} " && return 0
|
|
|
+ return 1
|
|
|
+}
|
|
|
+
|
|
|
+if check_port "$CONNECTOR_PORT"; then
|
|
|
+ log_warn "端口 ${CONNECTOR_PORT} 已被占用,请检查"
|
|
|
+fi
|
|
|
+if check_port "$RPC_PORT"; then
|
|
|
+ log_warn "RPC端口 ${RPC_PORT} 已被占用,请检查"
|
|
|
+fi
|
|
|
+
|
|
|
+# ======================== 创建目录 ========================
|
|
|
+log_step "创建目录: ${ZONE_DIR}"
|
|
|
+mkdir -p "${ZONE_DIR}"
|
|
|
+
|
|
|
+# ======================== 生成 _launch_server.xml ========================
|
|
|
+log_step "生成 _launch_server.xml ..."
|
|
|
+
|
|
|
+cat > "${ZONE_DIR}/_launch_server.xml" << XEOF
|
|
|
+<?xml version="1.0" encoding="utf-8"?>
|
|
|
+<doc>
|
|
|
+ <!-- ================================================================ -->
|
|
|
+ <!-- ${ZONE_NAME} 配置 (由 create_zone.sh 生成) -->
|
|
|
+ <!-- 区号: ${ZONE_ID} 端口: ${CONNECTOR_PORT} RPC: ${RPC_PORT} -->
|
|
|
+ <!-- Redis: db=${REDIS_DB} 生成时间: $(date '+%Y-%m-%d %H:%M:%S') -->
|
|
|
+ <!-- ================================================================ -->
|
|
|
+
|
|
|
+ <define name="GameNodeDefine" param1="" param2=""/>
|
|
|
+
|
|
|
+ <GlobalConfig>
|
|
|
+ <Env>dev</Env>
|
|
|
+ <Realm>${REALM_ID}</Realm>
|
|
|
+ <Mysql></Mysql>
|
|
|
+ <AcceptClientVersion>0.0.0</AcceptClientVersion>
|
|
|
+ <TemplateRoot>../../../data/ServerData/</TemplateRoot>
|
|
|
+ <NoticeErrorUrl>https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=d9d262b8-17c8-4297-8b9f-bb1b7f72ac89</NoticeErrorUrl>
|
|
|
+ <DebugPay>true</DebugPay>
|
|
|
+ <BattleRecordURLPrefix>https://zqtfcn.oss-cn-shanghai.aliyuncs.com/apollo_dev/server/playback/</BattleRecordURLPrefix>
|
|
|
+ </GlobalConfig>
|
|
|
+
|
|
|
+ <NameServer>
|
|
|
+ <RpcConfig>
|
|
|
+ <LocalEndPoint>${NAMESERVER_ENDPOINT}</LocalEndPoint>
|
|
|
+ <NetworkTimeoutMS>15000</NetworkTimeoutMS>
|
|
|
+ <RpcCodec>OpenCards.Server.Core.Serializer</RpcCodec>
|
|
|
+ </RpcConfig>
|
|
|
+ </NameServer>
|
|
|
+
|
|
|
+ <ServiceNodes>
|
|
|
+ <${GAME_NODE}>
|
|
|
+ <Redis>127.0.0.1,password=${REDIS_PASSWORD},allowAdmin=true,syncTimeout=30000,responseTimeout=30000,connectRetry=1000,connectTimeout=10000;db=${REDIS_DB}</Redis>
|
|
|
+ <Mysql>${MYSQL_CONN}</Mysql>
|
|
|
+ <Ip>127.0.0.1</Ip>
|
|
|
+ <RpcConfig>
|
|
|
+ <LocalNodeType>GameNode</LocalNodeType>
|
|
|
+ <LocalNodeName>${GAME_NODE}</LocalNodeName>
|
|
|
+ <LocalEndPoint>127.0.0.1:${RPC_PORT}</LocalEndPoint>
|
|
|
+ <NameServerEndPoint>${NAMESERVER_ENDPOINT}</NameServerEndPoint>
|
|
|
+ <RequestTickTimeMS>5000</RequestTickTimeMS>
|
|
|
+ <NetworkTimeoutMS>30000</NetworkTimeoutMS>
|
|
|
+ <DefaultTaskExecuteTimeout>60000</DefaultTaskExecuteTimeout>
|
|
|
+ <RpcCodec>OpenCards.Server.Core.Serializer</RpcCodec>
|
|
|
+ <AcceptTypeMappings>
|
|
|
+ <CenterService>OpenCards.Service.Center.CenterService</CenterService>
|
|
|
+ <AccountServer>OpenCards.Server.Account.AccountServer</AccountServer>
|
|
|
+ <ConnectorService>OpenCards.Server.Connector.ConnectorService</ConnectorService>
|
|
|
+ <ArenaManagerService>OpenCards.Server.Arena.ArenaManagerService</ArenaManagerService>
|
|
|
+ <ArenaValorService>OpenCards.Server.Arena.ArenaValorService</ArenaValorService>
|
|
|
+ <ArenaHighendService>OpenCards.Server.Arena.ArenaHighendService</ArenaHighendService>
|
|
|
+ <SessionService>OpenCards.Server.Connector.SessionService</SessionService>
|
|
|
+ <LogicService>OpenCards.Server.Logic.LogicService</LogicService>
|
|
|
+ <LogicManagerService>OpenCards.Server.Logic.LogicManagerService</LogicManagerService>
|
|
|
+ <StageRankService>OpenCards.Service.StageRank.StageRankService</StageRankService>
|
|
|
+ <ArenaPinnacleGameService>OpenCards.Server.Arena.ArenaPinnacleGameService</ArenaPinnacleGameService>
|
|
|
+ </AcceptTypeMappings>
|
|
|
+ </RpcConfig>
|
|
|
+ <StartService>
|
|
|
+ <LogicManagerService>
|
|
|
+ <ServiceName>LogicManagerService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>LogicManagerService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <FightPostURL>${FIGHT_POST_URL}</FightPostURL>
|
|
|
+ <serverID>${SERVER_ID}</serverID>
|
|
|
+ </Config>
|
|
|
+ </LogicManagerService>
|
|
|
+ <CenterService>
|
|
|
+ <ServiceName>CenterService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>CenterService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <serverID>${SERVER_ID}</serverID>
|
|
|
+ </Config>
|
|
|
+ </CenterService>
|
|
|
+ <StageRankService>
|
|
|
+ <ServiceName>StageRankService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>StageRankService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <serverID>${SERVER_ID}</serverID>
|
|
|
+ </Config>
|
|
|
+ </StageRankService>
|
|
|
+ <ArenaPinnacleGameService>
|
|
|
+ <ServiceName>ArenaPinnacleGameService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>ArenaPinnacleGameService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <ServerID>${SERVER_ID}</ServerID>
|
|
|
+ </Config>
|
|
|
+ </ArenaPinnacleGameService>
|
|
|
+ <ArenaManagerService>
|
|
|
+ <ServiceName>ArenaManagerService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>ArenaManagerService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <ServerID>${SERVER_ID}</ServerID>
|
|
|
+ </Config>
|
|
|
+ </ArenaManagerService>
|
|
|
+ <ArenaHighendService>
|
|
|
+ <ServiceName>ArenaHighendService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>ArenaHighendService</ServiceType>
|
|
|
+ <Config></Config>
|
|
|
+ </ArenaHighendService>
|
|
|
+ <ConnectorService>
|
|
|
+ <ServiceName>ConnectorService_${ZONE_ID}</ServiceName>
|
|
|
+ <ServiceType>ConnectorService</ServiceType>
|
|
|
+ <Config>
|
|
|
+ <ServerId>${SERVER_ID}</ServerId>
|
|
|
+ <Host>0.0.0.0</Host>
|
|
|
+ <Port>${CONNECTOR_PORT}</Port>
|
|
|
+ <NetCodec>OpenCards.Core.Serializer</NetCodec>
|
|
|
+ <KeepAlive>true</KeepAlive>
|
|
|
+ <KeepAliveInterval>30000</KeepAliveInterval>
|
|
|
+ <RecvBufferSize>16384</RecvBufferSize>
|
|
|
+ <SendBufferSize>16384</SendBufferSize>
|
|
|
+ <MaxConnections>300000</MaxConnections>
|
|
|
+ </Config>
|
|
|
+ </ConnectorService>
|
|
|
+ </StartService>
|
|
|
+ </${GAME_NODE}>
|
|
|
+ </ServiceNodes>
|
|
|
+</doc>
|
|
|
+XEOF
|
|
|
+
|
|
|
+# ======================== 生成管理脚本 ========================
|
|
|
+log_step "生成管理脚本..."
|
|
|
+
|
|
|
+# --- 公共工具函数 ---
|
|
|
+write_script_header() {
|
|
|
+ local file=$1
|
|
|
+ cat > "$file" << 'SHEOF'
|
|
|
+#!/bin/bash
|
|
|
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
+BASE_OUTPUT="/data/CzServer/_output.server"
|
|
|
+DLL="$BASE_OUTPUT/OpenCards.Server.DotNetCore.dll"
|
|
|
+LOG_DIR="$BASE_OUTPUT/logfile"
|
|
|
+mkdir -p "$LOG_DIR"
|
|
|
+
|
|
|
+GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
|
|
+SHEOF
|
|
|
+}
|
|
|
+
|
|
|
+# --- start.sh ---
|
|
|
+write_script_header "${ZONE_DIR}/start.sh"
|
|
|
+cat >> "${ZONE_DIR}/start.sh" << XEOF
|
|
|
+# ${ZONE_NAME} 启动脚本
|
|
|
+
|
|
|
+PID=\$(pgrep -f "server${ZONE_ID}/_launch_server.xml ${GAME_NODE}" 2>/dev/null)
|
|
|
+if [ -n "\$PID" ]; then
|
|
|
+ echo -e "\${YELLOW}[SKIP] ${ZONE_NAME} 已在运行 (PID: \$PID)\${NC}"
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+echo -e "\${GREEN}[START] ${ZONE_NAME} (端口:${CONNECTOR_PORT}, RPC:${RPC_PORT}, Redis:db=${REDIS_DB}) ...\${NC}"
|
|
|
+
|
|
|
+nohup dotnet "\$DLL" "\$SCRIPT_DIR/_launch_server.xml" ${GAME_NODE} global.RealmID=${REALM_ID} global.ServerID=${SERVER_ID} \
|
|
|
+ >> "\$LOG_DIR/server${ZONE_ID}.log" 2>&1 &
|
|
|
+
|
|
|
+sleep 3
|
|
|
+
|
|
|
+PID=\$(pgrep -f "server${ZONE_ID}/_launch_server.xml ${GAME_NODE}" 2>/dev/null)
|
|
|
+if [ -n "\$PID" ]; then
|
|
|
+ echo -e "\${GREEN}[OK] ${ZONE_NAME} 启动成功 (PID: \$PID)\${NC}"
|
|
|
+else
|
|
|
+ echo -e "\${RED}[FAIL] ${ZONE_NAME} 启动失败,查看日志:\${NC}"
|
|
|
+ tail -20 "\$LOG_DIR/server${ZONE_ID}.log"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+XEOF
|
|
|
+
|
|
|
+# --- stop.sh ---
|
|
|
+write_script_header "${ZONE_DIR}/stop.sh"
|
|
|
+cat >> "${ZONE_DIR}/stop.sh" << XEOF
|
|
|
+# ${ZONE_NAME} 停止脚本
|
|
|
+
|
|
|
+PID=\$(pgrep -f "server${ZONE_ID}/_launch_server.xml ${GAME_NODE}" 2>/dev/null)
|
|
|
+if [ -n "\$PID" ]; then
|
|
|
+ echo -e "\${YELLOW}[STOP] ${ZONE_NAME} (PID: \$PID)\${NC}"
|
|
|
+ kill \$PID
|
|
|
+ sleep 2
|
|
|
+ if pgrep -f "server${ZONE_ID}/_launch_server.xml ${GAME_NODE}" > /dev/null 2>&1; then
|
|
|
+ echo -e "\${RED}[KILL] 强制终止...\${NC}"
|
|
|
+ kill -9 \$PID 2>/dev/null
|
|
|
+ fi
|
|
|
+ echo -e "\${GREEN}[OK] ${ZONE_NAME} 已停止\${NC}"
|
|
|
+else
|
|
|
+ echo -e "\${YELLOW}[SKIP] ${ZONE_NAME} 未在运行\${NC}"
|
|
|
+fi
|
|
|
+XEOF
|
|
|
+
|
|
|
+# --- status.sh ---
|
|
|
+write_script_header "${ZONE_DIR}/status.sh"
|
|
|
+cat >> "${ZONE_DIR}/status.sh" << XEOF
|
|
|
+# ${ZONE_NAME} 状态查看
|
|
|
+
|
|
|
+PID=\$(pgrep -f "server${ZONE_ID}/_launch_server.xml ${GAME_NODE}" 2>/dev/null)
|
|
|
+if [ -n "\$PID" ]; then
|
|
|
+ echo -e "\${GREEN}[UP] ${ZONE_NAME} 运行中"
|
|
|
+ echo " PID: \$PID"
|
|
|
+ echo " 端口: ${CONNECTOR_PORT}"
|
|
|
+ echo " RPC: ${RPC_PORT}"
|
|
|
+ echo " 日志: \$LOG_DIR/server${ZONE_ID}.log\${NC}"
|
|
|
+else
|
|
|
+ echo -e "\${RED}[DOWN] ${ZONE_NAME} 未运行 (端口:${CONNECTOR_PORT})\${NC}"
|
|
|
+fi
|
|
|
+XEOF
|
|
|
+
|
|
|
+# --- restart.sh ---
|
|
|
+write_script_header "${ZONE_DIR}/restart.sh"
|
|
|
+cat >> "${ZONE_DIR}/restart.sh" << XEOF
|
|
|
+# ${ZONE_NAME} 重启脚本
|
|
|
+bash "\$SCRIPT_DIR/stop.sh"
|
|
|
+sleep 2
|
|
|
+bash "\$SCRIPT_DIR/start.sh"
|
|
|
+XEOF
|
|
|
+
|
|
|
+chmod +x "${ZONE_DIR}/start.sh" "${ZONE_DIR}/stop.sh" "${ZONE_DIR}/status.sh" "${ZONE_DIR}/restart.sh"
|
|
|
+
|
|
|
+# ======================== 输出 serverlist 条目 ========================
|
|
|
+cat << XEOF
|
|
|
+
|
|
|
+${GREEN}============================================
|
|
|
+ 请将以下条目添加到 OSS serverlist.json:
|
|
|
+============================================${NC}
|
|
|
+ {
|
|
|
+ "id": ${ZONE_ID},
|
|
|
+ "index": $((ZONE_ID - 1)),
|
|
|
+ "name": "${ZONE_NAME}",
|
|
|
+ "address": "${SERVER_PUBLIC_IP}:${CONNECTOR_PORT}",
|
|
|
+ "state": 1,
|
|
|
+ "is_open": true,
|
|
|
+ "capacity": 2000,
|
|
|
+ "serverid": ${SERVER_ID},
|
|
|
+ "groupid": ${REALM_ID},
|
|
|
+ "note": "测试服"
|
|
|
+ }
|
|
|
+${GREEN}============================================${NC}
|
|
|
+
|
|
|
+XEOF
|
|
|
+
|
|
|
+# ======================== 完成 ========================
|
|
|
+echo ""
|
|
|
+echo -e "${GREEN}============================================${NC}"
|
|
|
+echo -e "${GREEN} ${ZONE_NAME} 创建完成!${NC}"
|
|
|
+echo -e "${GREEN}============================================${NC}"
|
|
|
+echo ""
|
|
|
+echo -e " 目录: ${CYAN}${ZONE_DIR}${NC}"
|
|
|
+echo -e " 区号: ${CYAN}${SERVER_ID}${NC}"
|
|
|
+echo -e " 端口: ${CYAN}${CONNECTOR_PORT}${NC}"
|
|
|
+echo -e " RPC端口: ${CYAN}${RPC_PORT}${NC}"
|
|
|
+echo -e " Redis: ${CYAN}db=${REDIS_DB}${NC}"
|
|
|
+echo ""
|
|
|
+echo -e " 管理:"
|
|
|
+echo -e " ${CYAN}bash ${ZONE_DIR}/start.sh${NC} 启动"
|
|
|
+echo -e " ${CYAN}bash ${ZONE_DIR}/stop.sh${NC} 停止"
|
|
|
+echo -e " ${CYAN}bash ${ZONE_DIR}/status.sh${NC} 状态"
|
|
|
+echo -e " ${CYAN}bash ${ZONE_DIR}/restart.sh${NC} 重启"
|
|
|
+echo -e " ${CYAN}tail -f ${BASE_OUTPUT}/logfile/server${ZONE_ID}.log${NC} 日志"
|
|
|
+echo ""
|
|
|
+echo -e " ${YELLOW}⚠ 别忘了:${NC}"
|
|
|
+echo -e " 1. 更新 OSS serverlist.json(见上方)"
|
|
|
+echo -e " 2. 防火墙放行端口 ${CONNECTOR_PORT} 和 ${RPC_PORT}"
|
|
|
+echo ""
|