++Unity网络基础
++++Unity基本网络知识
++++NetworkManager类创建服务器和客户端
++++RPC(远程过程调用)技术
++++Unity网络管理器
++Unity网络:
++++NetworkServer 创建服务器(注册事件)
++++NetworkClient 连接服务器,注册事件,注册预设体
++++NetworkBehavior : IsLocalPlayer,区分不同网络对象的所有者
++++Rpc技术:
--Command :从客户端发起,在服务器执行。
--RpcClient : 从服务器发起,在客户端执行。
++++同步变量:
--[SyncVar] : float int v3[struct] string
++1、网络是什么?
++++网络:
++2、网络的作用?
++++1、信息交互
++++2、资源共享
++++3、分布式处理
++3、网络通讯协议
++++1、TCP/IP 4层模型
--应用层
--传输层
--互联网层
--网络接口层
++++2、TCP/IP 5层模型
--应用层
--传输层
--互联网层
--数据链路层
--物理层
++++3、OSI 7层模型
--应用层
--表示层
--会话层
--传输层
--网络层
--数据链路层
--物理层
++4、IP地址
++++网际协议地址
++++IPV4--32位
++++IPV6--128位
++5、NAT地址转换
++++PC1: 192.168.200.2
++++内网
++++SecPath F1000-E
++++外网
--PC2: 218.197.70.2
--PC3: 218.197.70.3
--PC4: ...
++6、端口Port
++++每个端口对应一个服务。
++7、软件系统体系结构
++++C/S
++++Client/Server
++++客户端/服务器
++8、网络游戏
++9、Unity网络框架解析
++++多人游戏和网络
++++Unity新版网络API
++++HLAPI架构图
++10、多人游戏和网络
++++思考一下,制作类似Data或者LOL这样的多人竞技游戏,需要实现那些功能?
++11、Unity新版网络API
++++Unity网络The High Level API(HLAPI)是为在Unity中创建多人在线游戏所建立的一套系统,HLAPI封装了网络游戏中大部分功能,提升开发效率,简化简单网络游戏的难度。
++++主要实现功能如下:
--网络状态管理[创建服务器、主机、客户端]
--状态同步
--过程过程调用
--互联网服务[中继服务器、游戏大厅、匹配比赛]
++12、HLAPI架构图
++++Low Level API
--Transport / Configuration
++++Messaging & Serialization
--Connection / Reader / Writer
++++Connection Management
--NetworkClient / NetworkServer
++++Object state & Actions
--NetworkIdentity / NetworkBehaviour
++++Object Life Cycle
--NetworkScene / ClientScene
++++Game Control
--NetworkManager
++++Player Control
--NetworkLobbyManager
++++Engine Integration
--NetworkTransform
--NetworkAnimator
--NetworkProimityChecker
++1.1、NetworkServer
++++NetworkServer类负责创建服务器监听接口,管理客户端的连接,它也负责处理游戏相关的一些特性: 玩家管理、监听、卵生对象和消息处理。
++1.2、Server方法(静态方法)
++++静态方法: 功能
++++Listen :根据指定端口开启服务器。
++++RegisterHandler :注册回调函数。
++++Spawn : 在所有已准备的客户端上实例化物体。
++++SpawnWithClientAuthority :跟Spawn()方法一样,并且设置客户端权限。
++++Destroy : 在所有客户端上删除物体。
++++AddPlayerForConnection :将卵生的物体与客户端建立关系。
++1.3、Server属性
++++静态变量 : 功能
++++active : 检查服务器是否开启。
++++connections : 当前所有连接的客户端列表。
++++handlers : 以字典形式返回服务器注册的所有回调方法。
++++listenPort : 服务器监听端口。
++++localClientActive : 在服务器上的客户端,即为主机是返回true。
++++maxDelay : 连接之间发送数据的最大延迟。
++1.4、创建服务器
Button StartServerButton;
void OnEnable(){
Application.runInBackground = true;
StartServerButton = GetComponent<Button>();
StartServerButton.onClick.RemoveAllListeners();
StartServerButton.onClick.AddListener(StartServer);
}
void StartServer(){
//服务器是否开启
if(!NetworkServer.active){
NetworkServer.Listen(7777); //根据指定端口,开启服务器
Debug.Log(“服务器开启”);
}
}
++2.1、NetworkClient
++++该类对象负责连接服务器,并与服务器通信(即收到服务器消息和发送消息给服务器)。
++2.2、Client方法
++++Connect : 根据指定IP和Port连接服务器。
++++RegisterHandler : 注册回调函数。
++2.3、创建客户端
++++NetworkClient用于连接服务器
Button clientButton;
NetworkClient client;
void OnEnable(){
clientButton = GetComponent<Button>();
clientButton.onClick.AddListener(Connect);
}
void Connect(){
client = new NetworkClient(); //创建一个客户端对象
client.RegisterHandler(MsgType.Connect, OnClientConnect); //注册回调函数
client.Connect(“127.0.0.1”,7777); //连接服务器
}
//成功连接服务器之后
void OnClientConnect(NetworkMessage netMsg){
clientButton.GetComponentInChildren<Text>().text = “连接成功!”;
}
++2.4、Client属性
++++Client属性
++3.1、卵生对象
++++网络中,所有网络对象都应该由服务器产生。
++++客户端玩家对象生成步骤:
--1、客户端发请求
--2、服务器接收请求后实例化客户端对象
++3.2、卵生对象步骤
++++1、新建预设体,添加NetWorkIdentity组件,标示为网络物体。
++++2、客户端调用ClientScene.Ready()方法告知服务器自己已经准备好。
++++3、客户端调用ClientScene.RegisterPrefab()注册网络预设体。
++++4、客户端调用ClientScene.AddPlayer()方法告诉服务器卵生对象。
++++5、服务器RegisterHandler->MsgType.AddPlayer的回调AddPlayer。
++++6、服务器在AddPlayer方法实例化物体,调用Spawn方法卵生。
++3.3、客户端代码
//成功连接服务器之后
void OnClientConnect(NetworkMessage msg){
clientButton.GetComponentInChildren<Text>().text = “连接成功!”;
ClientScene.Ready(msg.conn); //告诉服务器已就位
ClientScene.RegisterPrefab(playerPrefab); //提前注册网络预设体
ClientScene.AddPlayer(0); //告诉服务器实例化预设体,参数暂不重要
}
++3.4、服务器代码
void OnServerAddPlayer(NetworkMessage netMsg){
Debug.Log(“收到客户端发送添加玩家的请求”);
GameObject player = (GameObject)Instantiate(playerPrefab);
//将物体与客户端建立关系,即表示该物体由该客户端生成
NetworkServer.AddPlayerForConnection(netMsg.conn, player, 0);
//卵生[同步到其他客户端]
NetworkServer.Spawn(player);
}
++4.1、NetworkIdentity
++++NetworkIdentity组件是网络的核心,用NetworkServer.Spawn卵生的物体都必须具备该组件。该组件在卵生的时候会自动分配assetId和权限。
++++属性: 功能
++++isClient : 物体在客户端上时返回True。
++++isServer : 物体在服务器上时返回True。
++++hasAuthority : 有权限时返回True。
++++localPlayerAuthority : 只有当本地的客户端玩家时返回True。
++4.2、NetworkBehaiour
++++NetworkBehavior组件是一个特殊组件,它依赖NetworkIdentity组件,用来实现RPC技术和状态同步属性。我们想实现网络物体的控制脚本,必须继承自NetworkBehaviour。
public class PlayerScript:NetworkBehavior{
[SyncVar]
public int HP;
[ClientCallback] //表示只在客户端调用
void Update(){
if(isLocalPlayer){
//表示本地客户端玩家
h = Input.GetAxis(“Horizontal”);
v = Input.GetAxis(“Vertical”);
transform.Translate(new Vector(h,0,v) *Time.deltaTime);
}
}
}
++4.3、特性
++++NetworkBehaviour组件内包含的常用特性[Attrivute]如下:
--[SyncVar] : 用于标识序列化变量,实现变量同步。
--[Client] : 表示只能在客户端调用。
--[ClientCallback] : 表示客户端执行的回调。
--[Command] : 表示客户端向服务器发送的命令,在服务器执行。
--[ClientRpc] : 表示服务器向客户端发送的命令,在客户端执行。
++1、远程调用
++++网络系统可以实现客户端和服务器的通信,我们将这种通信称之为: 远程调用(Remote Procedure Calls),即RPC。
++++RPC框架可以方便实现方法调用,使用户不需要关心如何编码、连接和传输。
++++Unity中的RPC有两种类型:
--客户端调用服务器方法(Command)
--服务器调用客户端方法(ClientRpc)
++2、RPC类型图解
++++Command : 由客户端发送给服务器[在服务器执行方法]
++++ClientRPC : 由服务器发送给客户端[在客户端执行方法]
++3、RPC编程步骤
++++编程:
public class RPCTest:NetworkBehaviour{
private GameObject img;
void Start(){
img = Resources.Load(“Canvas”) as GameObject;
CmdTest();
}
void Update(){
if(!isLocalPlayer){
return;
}
if(Input.GetKeyDown(KeyCode.Space)){
CmdTest();
}
}
[Command] //表示为RPC方法--Command类型,方法名必须加前缀Cmd
void CmdTest(){ //Command方法只能在服务器调用
Instantiate(img);
Debug.Log(1);
}
}
++++前提: 创建好网络工程。
--第一步: 给客户端新建脚本RPCTest,继承自NetworkBehaviour。
--第二步: 创建Command方法或ClientRPC方法。
--第三步: 调用RPC方法。
++1、NetworkManager组件
++++网络管理器(NetworkManager)是Unity新版网络HLAPI中的一个核心组件,该组件封装了网络创建、运行和Debug等各种方法。
++++初级开发者,不需要写一行代码,即可实现简单的网络游戏。
++2、组件方法讲解
++++方法 : 功能
++++StartServer : 调用该方法,将开启一个新服务器。
++++OnStartServer : 回调方法,服务器开启后会自动调用该方法[On前缀方法为回调方法]
++++StartHost : 调用该方法,将开启一个主机。
++++OnStartHost : 回调方法,主机开启后会自动调用该方法。
++++OnServerConnect : 服务器回调方法,当有客户端连接时调用。
++++OnClientConnect : 客户端回调方法,当客户端连接到服务器时调用。
++练习:
++++新建脚本MyNetworkManager组件,继承自NetworkManager组件,使用OnGUI回调函数,绘制按钮,开启服务器,并在服务器开启之后自动输出:Server OK!
++++NetworkManager组件在UnityEngine.Networking命名空间下。
++++思考:
public class MyNetworkManager:NetworkManager{
bool isAtStartUp = false;
void OnGUI(){
if(isAtStartUp){
this.enabled=false;
}
if(GUILayout.Button(“创建服务器”)){ //客户端如何连接?
StartServer();
isAtStartUp = true;
}
}
public override void OnStartServer(){
base.OnStartServer();
print(“Server OK!”);
}
}
++组件属性讲解
++3、使用步骤
++++1、新建场景A,新建一个空物体,并给其添加NetworkManager组件和NetworkManagerHUD组件。
++++2、保存场景,并添加到Scenes In Build中。
++++3、将场景A拖到NetworkManager的Offline Scene框中。
++++4、新建场景B,保存并添加到Scenes In Build中。
++++5、将场景B拖到NetworkManager的Online Scene中。
++++6、新建一个小球,添加组件Network Identity组件,勾选Local Player Authority选项,拖成预设体,在Hierarchy视图中删除该物体。
++++7、将预设体小球拖到NetworkManager的Player Prefab框中,运行程序。
++总结
++++NetworkManager包含功能如下:
--游戏状态管理
--卵生管理
--场景管理
--Debug输出
--匹配比赛
--用户自定义
++UNet的一个简单应用
++++MyNet_AppConst.cs
++++Scene02NetWorkManager.cs
++++Scene02PlayerAController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyNet_AppConst{
public const int myServerPort=34567;
public const string myServerIp= “127.0.0.1”;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //引入UI命名空间
using unityEngine.Networking; //引入Unet网络命名空间
publicclassScene02NetWorkManager:MonoBehaviour{
[HideInInspector]
public static Scene02NetWorkManager MyNetInstance; //一个快捷访问简单实例
Button m_createServerBtn; //1、创建服务器button
Button m_connectServBth;
InputField m_myInputServIp;
InputField m_myInputServPort;
NetworkClient m_MyClient;
public GameObject mPlayerPrefab; //16、增加玩家
private void Awake(){
myNetInstance = this;
//0、后台运行
Application.runInBackground = true;
}
void Start(){
//2、找到创建服务器的button
m_createServerBtn = GameObject.Find(“Button_CreateServer”).GetComponent<Button>();
m_createServerBtn.onClick.AddListener(OnMyServerInitAction);
m_MyClient = new NetworkClient();
m_connectServBtn = GameObject.Find(“Button_ConnectServer”).GetComponent<Button>();
m_connectServBtn.onClick.AddListener(OnMyClientConnectToServAction);
m_myInputServIp = GameObject.Find(“InputField_ServIP”).GetComponent<InputField>();
m_myInputServPort = GameObject.Find(“InputField_ServPort”).GetComponet<InputField>();
}
void Update(){
}
//3、创建服务器
private void OnMyServerInitAction(){
//4、启动服务器
bool bListen = NetworkServer.Listen(MyNet_AppConst.myServerPort);
if(bListen){
m_createServerBtn.interactable = false; //取消交互
}else{
}
//5、MsgType事件注册方法
//MsgType.AddPlayer;
//MsgType.Animation;
//MsgType.AnimationParameters;
//MsgType.AnimationTrigger;
//MsgType.Command;
//MsgType.Connect;
//MsgType.CRC;
//MsgType.Disconnect;
//MsgType.Error;
//MsgType.Fragment;
//5、为事件注册方法
NetworkServer.RegisterHandler(MsgType.AddPlayer, OnMyServerAddPlayer);
NetworkServer.RegisterHandler(MsgType.Connect, OnMyServerConnectTo); //一旦有人连接到服务器,就会执行
NetworkServer.RegisterHandler(MsgType.Disconnect, OnMyServerDisConnect);
//22、对服务器玩家的创建过程单独处理
m_MyClient = ClientScene.ConnectLocalServer();
m_MyClient.RegisterHandler(MsgType.Conncet, OnMyClientConnectSuccess);
}
//6、收到客户端添加玩家的请求
private void OnMyServerAddPlayer(NetworkMessage netMsg){
//18、收到了客户端发送的添加玩家的消息
float randomPos = UnityEngine.Random.Range(-2,2);
GameObject playerA = GameObject.Instantiate(myPlayerPrefab, new Vector3(randomPos, 1,randomPos), Quaternion.identity);
//19、为该游戏对象指明权限
NetworkServer.AddPlayerForConnection(netMsg.conn, playerA, 0);
//20、卵生出去
NetworkServer.Spawn(playerA);
}
//7、有人连接服务器的回调方法
private void OnMyServerConnectTo(NetworkMessage netMsg){
}
//8、有人断开服务器的回调方法
private void OnMyServerDisConnect(NetworkMessage netMsg){
}
//点击连接服务器的事件
private void OnMyClientConnectToServAction(){
//12、连接服务器
string servIpStr;
int servPortInt;
if(m_myInputServIp.text.Length == 0){
servIpStr = MyNet_AppConst.myServerIp;
}else{
servIpStr = m_myInputServIp.text;
}
if(m_myInputServPort.text.Length == 0){
servPortInt = MyNet_AppConst.myServerPort;
}else{
servPortInt = int.Parse(m_myInputServPort.text);
}
m_MyClient.Connect(servIpStr, servPortInt); //连接服务器
//13、注册连接成功的回调
m_MyClient.RegisterHandler(MsgType.Connect, OnMyClientConnectSuccess);
}
//14、客户端连接服务器成功的方法
public void OnMyClientConnectSuccess(NetworkMessage netMsg){
//15、告诉服务器,当前客户端已经准备好
ClientScene.Ready(netMsg.conn);
//21、注册预制体
ClientScene.RegisterPrefab(mPlayerPrefab); //fix:特别重要
//17、实例化预设体
//网络游戏对象必须由服务器产生,卵生到客户端
ClientScene.AddPlayer(0); //发送 //fix:特别重要
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Scene02PlayerAContoller:NetworkBehaiour{
float hor,ver;
public GameObject bulletPrefab; //子弹预设体
public Transform firePos; //炮口
//计时器
public float myTimer=0f;
public float myTimeCd=1f;
//血条
public Scrollbar myScrollbar; //血条
//血量--全局变量(客户端修改,所有客户端同步修改)
//同步变量的修改,一定要通过服务器。
[SyncVar]
float hp = 100; //血量
void Start(){
//血条需要共同刷新
myScrollbar.size = hp/100f; //设置血条百分比
myScrollbar.transform.rotation=Camera.main.transform.rotation; //血条和主摄像机四元数方向一致
if(isLocalPlayer == false){
return;
}
hor=Input.GetAxis(“Horizontal”);
ver=Input.GetAxis(“Vertical”);
if(hor!=0){
transform.Rotate(Vector3.up*Time.deltaTime*180f*hor);
}
if(ver!=0){
transform.postion+=transform.forward*Time.deltaTime*3f*ver;
}
//开火
myTimer -= Time.deltaTime;
if(Input.GetMouseButtonDown(0)){
if(myTimer<=0){
Cmd_MyPlayer_Fire();
myTimer = myTimeCd;
}
}
//模拟受到伤害
if(Input.GetKeyDown(KeyCode.Space)){
Cmd_MyPlayer_TakeDamage(10f);
}
}
//开火
[Commad]
public void Cmd_MyPlayer_Fire(){
//服务器中执行
GameObject mybullet = GameObject.Instantiate(bulletPrefab, firePos.position, firePos.rotation);
Rigidbody rig = mybullet.GetComponent<Rigidbody>();
rig.velocity = mybullet.transform.forward*100f;
Destroy(mybullet, 5f);
NetworkServer.Spawn(mybullet);
}
//受到伤害
[Command]
public void Cmd_MyPlayer_TakeDamage(float damage){
hp -= damage;
if(hp <= 0){
NetworkServer.Destroy(gameObject);
}
}
}
++Unity的UNET组件
++++新建一个UnetProject。
++++新建一个GameObject重命名为Network Manager,给它添加Network Manager组件,这是Unet提供的一个核心管理组件,可以在脚本里访问Network Manager进行网络开发。
++++还需要添加一个Network Manager HUD组件,这个用来显示UI,UI上的按钮会跟Network Manager交互。
++Network Manager HUD组件
++++LAN Host(H) : 把本机作为Server + Client,即服务器加客户端。
++++LAN Client(C) : 与服务器连接,后面填ip地址(localhost就是本机)。
++++LAN Server Only(S) : 本机只作为服务器。
++++一般在测试时才会用这个组件。
++搭建一个Player
++++现在用Unity自带的模型拼装一个Player出来(随便就行),给他添加Network Identity组件,这是一个网络标识符,拥有标识符的物体可以在网络上生成,也就是同步到其他客户端。
++++Server Only :只会在服务器端时才有权限对他进行操作。
++++Local Player Authority : 会在客户端时有权限,是一个局部角色。
++++我们给Player选中Local Player Authority,表示运行时连接上服务器我们也可以对他进行操作。
++++为了让他能在局域网生成,这表示我们要生成的角色是哪个,这样在每次联机时Network Manager会自动根据Player Prefab创建一个角色。
++++Auto Create Player : 每次服务器,客户端连接都会创建一个Player,现在运行看见的效果不明显,优化角色控制后再运行看效果。
++++新建PlayerController脚本并编辑:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
//为了能让脚本在连上局域网的同时还能分别控制物体,需要继承NetworkBehaviour
public class PlayerController:NetworkBehaviour{
public float traSpeed = 3; //移动的速度
public float rotSpeed=120; //一秒旋转的角度
void Update(){
if(!isLocalPlayer){
//isLocalPlayer是NetworkBehaviour的内置属性
//如果不是本地客户端,就返回,不执行下面的操作
return;
}
float h = Input.GetAxis(“Horizontal”);
float v = Input.GetAxis(“Vertical”);
transform.Translate(Vector3.forward*v*traSpeed*Time.deltaTime); //朝某个方向移动
transform.Rotate(Vector3.up* h *rotSpeed*Time.deltaTime); //围绕某轴旋转
}
}
++添加Network Transform组件
++++还需要给Player添加一个Network Transform组件,这是一个同步Transform的组件,包括:position、rotation、scale。它的同步是单向的,就是将你控制的物体同步到其他客户端,当你在服务端改变物体时,客户端不会跟着改变。
++添加差异化脚本
++++两个角色看起来一样,添加控制脚本。
//这是重写NetworkBehaviour内的方法
//这个方法只会在创建本地角色时调用
public override void OnStartLocalPlayer(){
GetComponent<MeshRenderer>().material.color = Color.bule;
}
++++运行:
++++自己控制的是蓝色,另外一个是默认的白色。
++给角色添加枪和子弹
++++给角色添加上枪和子弹,让他可以射击。
++++还要给子弹添加上Rigidbody组件,取消重力。
++++把枪的碰撞器去掉,它不需要做检测。
#立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++立钻哥哥推荐的拓展学习链接(Link_Url):
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++Unity引擎基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.csdn.net/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.csdn.net/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.csdn.net/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.csdn.net/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.csdn.net/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.csdn.net/vrunsoftyanlz/article/details/79254902
++++C#事件:https://blog.csdn.net/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.csdn.net/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.csdn.net/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.csdn.net/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.csdn.net/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.csdn.net/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++设计模式简单整理:https://blog.csdn.net/vrunsoftyanlz/article/details/79839641
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++UML类图:https://blog.csdn.net/vrunsoftyanlz/article/details/80289461
++++Unity知识点0001:https://blog.csdn.net/vrunsoftyanlz/article/details/80302012
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372628
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft : lovezuanzuan--_--