仿LOL项目开发第一天

---恢复内容开始---

仿LOL项目开发第一天

                                by---草帽

                           项目源码研究群:539117825

最近看了一个类似LOL的源码,颇有心得,所以今天呢,我们就来自己开发一个类似于LOL的游戏demo。

可能项目持续的时间会比较久,主要是现在还在上学,所以基本上是在挤出一点课余时间来写的博客。

如果项目更新慢,还请各位谅解。

这个项目呢,大家可以跟着我的步骤一起做。博客上我会尽量的详细的教大家如何制作一款商业游戏。

OK,回归正题。现在我们来做游戏的前期准备工作:

1.Unity3d--->版本5.0以上,我用的5.3.1版本

2.Eclipse---->版本随意,但是jdk的版本要1.7以上

3.php+mysql+apache,可以去网上搜下:WampServer,里面集成了这些工具。

正式开始:

1.打开Unity5,新创建一个项目,取名为LOLGameDemo:

2.创建文件夹用来存放各种资源,比如Resources,Scripts,Scenes等,然后导入插件NGUI。

这里我用的是3.9.0版本的。

3.制作一个新的场景,我们取名为Login,存放在Scenes文件目录下,为什么取名为Login,就像LOL一样,我们一打开游戏是不是就是登陆界面。可能有些童鞋会问,不是还有更新吗,没有错,我们把更新部分的代码,集成到了Login场景中。

4.编写脚本,这是我们程序的第一个脚本,第一个脚本通常来做什么?

没错就是驱动其他脚本的执行,比如检测更新,资源加载等等等等。

那么,我们在Scripts文件下创建:LOLGameDriver.cs驱动脚本,然后在Hierachy窗口创建一个空物体,取名为LOLGameDriver,来存放这个脚本。

打开编辑脚本:

由于是驱动器,在整个游戏中,肯定只需用到一个,所以我们得设计成单例。

 

using UnityEngine;
using System.Collections;
/// <summary>
/// 驱动脚本
/// </summary>
public class LOLGameDriver : MonoBehaviour 
{/// <summary>/// 静态单例属性/// </summary>public static LOLGameDriver Instance{get;set;}void Awake (){//如果单例不为空,说明存在两份的单例,就删除一份if (Instance != null){Destroy(this.gameObject);return;}Instance = this;//初始化单例DontDestroyOnLoad(this.gameObject);Application.runInBackground = true;//可以在后台运行Screen.sleepTimeout = SleepTimeout.NeverSleep;//设置屏幕永远亮着}void Start () {}void Update () {}
}

  

5.编写检测版本更新的情况。

在编写代码之前,我们先来制作登陆界面,不然运行的时候空白的界面显得不好看。

这里我创建了一个Temp来存放临时的Textures,因为我们界面用到的只是图集,并不是这些textures,所以制作完图集之后,就可以直接删了。

我们打开NGui的制作图集的工具,然后制作Login.altas图集,存放在新建的Altas文件夹下面:

关于登录界面的Textures,我会在文章的最后部分提供链接。

制作玩图集之后,我们开始拼凑界面。不论怎么说制作界面是最烦的时候,也是最浪费时间。

这个是我随手搭建的登陆界面:这里主要分两块

1.LoginFrame---->就是整体的框架,不包括右边有用户名输入的UI

2.Login------>这个是右边有用户名输入框的UI

为什么要分这两部分,你想想看,如果LOL游戏要更新的时候,是不是就只有背景图片,并没有用户名输入框那个UI。所以我们要独立出用户名那个UI,动态来加载他。

那么,我们就要把它制作成Prefab。

在Resources文件下,创建Guis文件目录,然后拖拽Login到文件中。

具体界面怎么制作,你们自己搞,我这里就不再详细的讲解。

OK,那么接下来,我们开始编写程序。

回到LOLGameDriver脚本内,新建一个public方法,取名为TryInit();主要是用来检测是否有网络和版本更新。

首先是网络是否可行的检测:

我们新建一个类:CheckTimeout.cs专门用来检测网络是否良好。

在写之前,我们考虑下,这个类是用来检测网络性能,而其中需要有下载功能,所以违背了类的单一职责原则,我们设计的类的时候,尽量不要让他太过于复杂。

所以处理下载功能的,我们专门写个DownloadMgr.cs来处理。

我们新建一个下载类,由于你的下载管理器也肯定是只在内存中存在一份,所以我们设计成单例:

 

using UnityEngine;
using System.Collections;
using System;
using System.Net;
public class DownloadMgr 
{private static DownloadMgr m_oInstance;private WebClient m_oWebClient;public static DownloadMgr Instance {get {if (m_oInstance == null){m_oInstance = new DownloadMgr();}return m_oInstance;}}public DownloadMgr(){this.m_oWebClient = new WebClient();}/// <summary>/// 异步下载网页文本/// </summary>/// <param name="url"></param>/// <param name="AsynResult"></param>/// <param name="onError"></param>public void AsynDownLoadHtml(string url, Action<string> AsynResult, Action onError){Action action = () =>{string text = DownLoadHtml(url);if (string.IsNullOrEmpty(text)){if (onError != null){onError();}}else {if (AsynResult != null){AsynResult(text);}}};//开始异步下载action.BeginInvoke(null, null);}/// <summary>/// 下载网页的文本/// </summary>/// <param name="url"></param>/// <returns></returns>public string DownLoadHtml(string url){try{return this.m_oWebClient.DownloadString(url);}catch (Exception e){Debug.LogException(e);return string.Empty;}}
}

只要在CheckTImeout类里面调用DownloadMgr的AsynDownloadHtml()方法,就可以进行异步下载,然后初始化带参的委托。我们看看CheckTimeout.cs代码:

using UnityEngine;
using System.Collections;
using System;
/// <summary>
/// 检测网络是否超时类
/// </summary>
public class CheckTimeout 
{/// <summary>/// 是否网络超时,这里使用百度做测试/// </summary>/// <param name="AsynResult"></param>public void AsynIsNetworkTimeout(Action<bool> AsynResult){TryAsynDownloadHtml("http://www.baidu.com", AsynResult);}private void TryAsynDownloadHtml(string url, Action<bool> AsynResult){DownloadMgr.Instance.AsynDownLoadHtml(url, (text) => {if (string.IsNullOrEmpty(text)){AsynResult(false);}else {AsynResult(true);}}, () => { AsynResult(false); });}
} 

再回到LOLGameDriver脚本:在TryInit()方法里面编写代码:

 

public void TryInit(){//说明网络可以if (Application.internetReachability != NetworkReachability.NotReachable){CheckTimeout checkTimeout = new CheckTimeout();checkTimeout.AsynIsNetworkTimeout((result) => {//网络良好if (result){//开始更新检测}else //说明网络错误{//开始消息提示框,重试和退出}});}}

可能读者看到这样的代码,就是委托比较多的代码,头就很晕。其实委托很简单,你们只要记住,委托就是方法指针。用来干嘛,解耦和用的。

你看如果不用委托,是不是LOLGameDriver得注入到CheckTimeout和DownloadMrg里面充当依赖,但是委托直接把LOLGameDriver的里面的匿名委托当做方法指针传递到DownloadMrg里面执行。

 

OK,讲完网络监测之后,我们来讲讲版本检测更新。

我们在LOLGameDriver的网络良好的判断里面,新增一个方法:DoInit();

那么我们知道,所谓的版本更新,无非就是服务端的版本信息和客户端版本信息的对照。

那么客户端的版本信息保存在哪里?没错就是Application.persistentDataPath这个持久文件路径。

所以我们新建一个类,专门管理这些与系统有关的路径:SystemConfig.cs:

 

using UnityEngine;
using System.Collections;
/// <summary>
/// 系统参数配置
/// </summary>
public class SystemConfig
{public readonly static string VersionPath = Application.persistentDataPath + "/version.xml";
}

里面存放的是本地版本信息的xml文件路径:VersionPath

因为涉及到版本控制,所以我们得有个VersionManager单例来管理。

新建一个VersionManager.cs脚本:

有没有突然发现,几乎所有的管理器都是单例模式的,你我们每个管理器都需要写个的单例,那不是特别的麻烦,所以呢,这里教大家一个小技巧:继承单例。

我们写个抽象单例的父类,放在命名空间:Game下面。

 

using System;
using System.Threading;
namespace Game
{public class Singleton<T> where T : new(){private static T s_singleton = default(T);private static object s_objectLock = new object();public static T singleton{get{if (null == Singleton<T>.s_singleton){object obj;Monitor.Enter(obj = Singleton<T>.s_objectLock);try{if (null == Singleton<T>.s_singleton){Singleton<T>.s_singleton = ((default(T) == null) ? Activator.CreateInstance<T>() : default(T));}}finally{Monitor.Exit(obj);}}return Singleton<T>.s_singleton;}}protected Singleton(){}}
}

 

这个单例是多线程安全的。

所以我们的VersionManager就直接继承该抽象类,注意需要引用Game命名空间:

 

using UnityEngine;
using System.Collections;
using Game;
public class VersionManager : Singleton<VersionManager>
{}

OK,正式进入VersionManager代码的编写,我们先来分析一下:

1.VersionManager的初始化,主要处理事件的注册和监听。

2.VersionManager加载本地版本信息xml,封装成版本信息类VersionManagerInfo来管理。

3.检查网络情况,开始下载服务器版本信息,也封装成VersionManagerInfo类的实例来管理。

4.对比服务器和客户端版本信息,如果一致无需更新,如果不一致,则下载资源,界面显示下载进度,完成之后,解压缩到游戏文件夹内完成更新。

先是第一步初始化,因为我们还没涉及到什么事件,所以我们先写个Init()初始化方法,等以后用到再在里面写,所以写个空的Init()。

 

public void Init()
{}

 

 

第二步:加载本地版本信息,因为我们的版本信息需要进行对照,所以创建一个版本信息类来管理方便点,所以创建一个VersionManagerInfo类:

 

public class VersionManagerInfo 
{/// <summary>/// 游戏程序版本号,基本上我们不会替换游戏程序,除非非得重新下载客户端/// </summary>public VersionCodeInfo ProgramVersionCodeInfo;/// <summary>/// 游戏资源版本号/// </summary>public VersionCodeInfo ResourceVersionCodeInfo;public string ProgramVersionCode{get {return ProgramVersionCodeInfo.ToString();}set {ProgramVersionCodeInfo = new VersionCodeInfo(value);}}public string ResourceVersionCode {get {return ResourceVersionCodeInfo.ToString();}set {ResourceVersionCodeInfo = new VersionCodeInfo(value);}}/// <summary>/// 资源包列表/// </summary>public string PackageList { get; set; }/// <summary>/// 资源包地址/// </summary>public string PackageUrl { get; set; }/// <summary>/// 资源包md5码列表/// </summary>public string PackageMd5List { get; set; }/// <summary>/// 资源包字典key=>url,value=>md5/// </summary>public Dictionary<string, string> PackageMd5Dic = new Dictionary<string, string>();public VersionManagerInfo(){ProgramVersionCodeInfo = new VersionCodeInfo("0.0.0.1");ResourceVersionCodeInfo = new VersionCodeInfo("0.0.0.0");PackageList = string.Empty;PackageUrl = string.Empty;}
} 

 

VersionCodeInfo.cs:

 

/// <summary>
/// 版本号
/// </summary>
public class VersionCodeInfo 
{/// <summary>/// 版本号列表/// </summary>private List<int> m_listCodes = new List<int>();/// <summary>/// 初始化版本号/// </summary>/// <param name="version"></param>public VersionCodeInfo(string version){if (string.IsNullOrEmpty(version)){return;}string[] versions = version.Split('.');for (int i = 0; i < versions.Length; i++){int code;if (int.TryParse(versions[i], out code)){this.m_listCodes.Add(code);}else {Debug.LogError("版本号不是数字");this.m_listCodes.Add(code);}}}/// <summary>/// 比较版本号,自己大返回1,自己小返回-1,一样返回0/// </summary>/// <param name="codeInfo"></param>/// <returns></returns>public int Compare(VersionCodeInfo codeInfo){int count = this.m_listCodes.Count < codeInfo.m_listCodes.Count ? this.m_listCodes.Count : codeInfo.m_listCodes.Count;for (int i = 0; i < count; i++){if (this.m_listCodes[i] == codeInfo.m_listCodes[i]){continue;}else {return this.m_listCodes[i] > codeInfo.m_listCodes[i] ? 1 : -1;}}return 0;}/// <summary>/// 重写ToString()方法,输出版本号字符串/// </summary>/// <returns></returns>public override string ToString(){StringBuilder sb = new StringBuilder();foreach (var code in this.m_listCodes){sb.AppendFormat("{0}.", code);}//移除多余出来的.号sb.Remove(sb.Length - 1, 1);return sb.ToString();}
}

ok,我们回到VersionManager中,定义一个LocalVersion属性,类型是VersionManagerInfo类型。

 

public VersionManagerInfo LocalVersion { get; private set; }

然后在LoadLocalVersion()方法里面初始化,怎么初始化,我们需要读取version.xml里面的内容,然后初始化。因为我们程序刚开始是不存在SystemConfig.VersionPath的文件,所以呢,我们要自己写个xml文件,放在Resource下面,然后在保存到SystemConfig.VersionPath路径上去。

 

    public void LoadLocalVersion(){//如果已经存在本地版本文件if (File.Exists(SystemConfig.VersionPath)){}else {LocalVersion = new VersionManagerInfo();//默认版本的初始状态0.0.0.0TextAsset ver = Resources.Load("version") as TextAsset;if (ver != null){UnityTools.SaveText(SystemConfig.VersionPath, ver.text);}}}

所以,创建一个xml文件,命名为version.xml放在Resources根目录下面。(其实这个xml是打包的时候自动生成的,这里我简化下,先不讲打包)

<?xml version="1.0" encoding="utf-8"?>
<root><ProgramVersionCode>0.0.0.1</ProgramVersionCode><ResourceVersionCode>0.0.0.0</ResourceVersionCode><PackageList></PackageList><PackageUrl></PackageUrl><PackageMd5List></PackageMd5List>
</root>

这个xml标签的名字要和VersionManagerInfo类的属性名一致。

UnityTools.SaveText(SystemConfig.VersionPath, ver.text);

 

这个方法我抽象出来到工具类里面去,功能是将string内容保存到一个文本文件内。

 

     /// <summary>/// 保存文本到指定文件路径/// </summary>/// <param name="filePath"></param>/// <param name="textContent"></param>public static void SaveText(string filePath, string textContent){//如果不存在该目录就创建if (!Directory.Exists(GetDirectoryName(filePath))){Directory.CreateDirectory(GetDirectoryName(filePath));}//如果已经存在该文件就删除if (File.Exists(filePath)){File.Delete(filePath);}//创建文件并写入内容using (FileStream fs = new FileStream(filePath, FileMode.Create)){using (StreamWriter sw = new StreamWriter(fs)){sw.Write(textContent);sw.Flush();sw.Close();}fs.Close();}}/// <summary>/// 取得该文件所在的目录文件夹/// </summary>/// <param name="filePath"></param>/// <returns></returns>public static string GetDirectoryName(string filePath){return filePath.Substring(0, filePath.LastIndexOf('/'));}

OK,那么加载本地版本资源完成之后,进行第三步:检查网络情况,开始下载服务器版本信息

我们知道,下载服务器版本信息,肯定涉及到界面的同步,比如下载更新消息提示框,下载进度条等等。那么,如果把这些界面都放在VersionManager或者DownloadMrg类里面处理,不符合类的单一职责,也不符合mvc模式,所以呢。

之前我们讲过,用委托来处理,把界面的处理直接通过委托传递到VersionManager或者DownloadMrg类里面。

我们回到LOLGameDriver类的DoInit()方法:

    public void DoInit(){VersionManager.singleton.Init();VersionManager.singleton.LoadLocalVersion();CheckVersion(CheckVersionFinished);}

CheckVersion(Action finished):

private void CheckVersion(Action finished){//添加一个解压文件界面提示回调Action<bool> fileDecompress = (finish) => {if (finish){//正在更新本地文件,原本是界面上显示提示消息,以后再讲,这里只是打印看看Debug.Log("正在更新本地文件");}else {Debug.Log("数据读取中");}};Action<int, int, string> taskProgress = (total, index, fileName) => { //正在下载更新文件Debug.Log(string.Format("正在下载更新文件({0}/{1}:{2})", index + 1, total, fileName));};Action<int, long, long> progress = (ProgressPercentage, TotalBytesToReceive, BytesReceive) => {//处理进度条Debug.Log(string.Format("进度:{0}%" ,ProgressPercentage));};Action<Exception> error = (ex) => {Debug.Log(ex);};//界面提示版本检查中Debug.Log("版本检查中...");VersionManager.singleton.CheckVersion(fileDecompress, taskProgress, progress, finished, error);}

这里我将这些委托直接定义在方法内部,其实我们可以自己在外部定义这些方法的,其实都是一样的。

Ok,写到在运行程序试试。唉!发现有报错误:

他说Application.persistentDataPath这个方法得在主线程里面执行,也就是说我们把它放在另外一个线程里面执行了。想想,我们哪里有用到另外一个线程。哦,对了,在Donwload的时候,我们异步下载一个网页资源。

也就是这个委托出现错误,他是在另外一个线程里面执行,然后调用LOLGameDriver.TryInit()->DoInit()->VersionManager.singleton.LoadLocalVersion();

所以他取得Application.persistentDataPath是在

action.BeginInvoke(null, null);

线程下面执行的。那么如何解决这个问题呢?关键是这个委托放在Update,Awake,Start或者协程里面执行,且只执行一次。

对了,之前看过我博客的童鞋可以很快想到--->时间定时器

我们在LOLGameDriver类下面写个Tick方法,执行时间定时器的Tick计时:

 

    private void Tick(){TimerHeap.Tick();}  

 

然后在Awake里面,不断的重复执行这个Tick,实际上就是一个协程。

 

InvokeRepeating("Tick", 1, 0.02f);

 

然后在创建一个添加委托执行的接口,Invoke(Action action):

 

    public static void Invoke(Action action){TimerHeap.AddTimer(0, 0, action);} 

 

将这个委托添加到定时器里面执行,默认为0秒之后执行,无重复(0=无重复)执行。

OK,我们只需要修改一处就可以了:

 

 将红色代码注释,然后添加蓝色代码就ok了。运行,观察打印信息:

OK,行了,那么本节就到这里,下节继续。。。。。。

Login界面UI下载链接

 

 仿LOL项目开发第二天链接地址

 

 

转载于:https://www.cnblogs.com/CaomaoUnity3d/p/5456549.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/256391.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

linux 用户创建时间,在linux中如何能得知一个用户的创建时间?

在linux中如何能得知一个用户的创建时间&#xff1f; (2011-08-24 03:36:01) 标签&#xff1a; 杂谈 在linux中如何能得知一个用户的创建时间&#xff1f;如题。之前我试过id、passwd以及通过stat查看用户主目录的创建时间&#xff0c;但是都不能准确地反映这个用户的 创建时间…

印尼玩lol注册哪个服务器,《LOL手游》印尼服怎么注册 安卓IOS注册流程攻略

导 读 LOL手游印尼服终于上线咯。相信大家都想去尝试一波&#xff0c;印尼服作为国际外服&#xff0c;想要体验就需要注册账号哦&#xff0c;下面九游小编就带来详细注册方法&#xff0c;快来看看吧~ 云顶之弈手游安卓ios注册流程详解 国服英雄联盟... LOL手游印尼服终于上线咯…

印尼玩lol注册哪个服务器,LOL手游印尼服怎么注册 LOL手游印尼服账号注册方法介绍...

版本&#xff1a;v1.0 类型&#xff1a;MOBA跑酷大小&#xff1a;1 MB评分&#xff1a;9.2 标签&#xff1a; moba 策略 立即下载 LOL手游目前还没在中国上线&#xff0c;我国玩家想要提前体验可以先去别国服玩&#xff0c;印尼服就是一个不错的选择&#xff0c;不少小伙伴好奇…

【PWN · ret2text | PIE 】[NISACTF 2022]ezpie

简单的PIE绕过 目录 前言 一、题目重述 二、解题思路 1.现有信息 2.思考过程 3.exp 总结 前言 所接触的PIE保护的第一题&#xff0c;也非常简单。 一、题目重述 二、解题思路 1.现有信息 PIE保护——程序可能被加载到任意位置&#xff0c;所以位置是可变的。程序返回…

JRE和JDK

JRE (Java Runtime Environment) 是Java程序的运行时环境&#xff0c;包含JVM 和运行时所需要的核心类库。我们想要运行一个已有的Java程序&#xff0c;那么只需安装JRE即可。 JDK (Java Development Kit) 是Java程序开发工具包&#xff0c;包含JRE和开发人员使用的工具。 其中…

分享一个下载软件的html

主要是html与js,css实现 页面如下: 点击软件后会滑动到,软件介绍,然后弹出二维码: <!DOCTYPE HTML> <!--HTML for wufuba.comAuthor: www.wufuba.com --> <html lang="zh-cmn-Hans"><head><title>xxx软件</title><m…

绝地求生无盘服务器,无盘网吧里绝地求生进不去?他们是这么解决的

2018-3-9日应该算是绝地求生网吧界的一个大日子&#xff0c;因为在这一天绝地求生在官方未发布公告(更新完成后才补发的)的情况下开始了不停机更新游戏。然鹅更新后&#xff0c;多家网吧表示进不去游戏了&#xff0c;出现各种错误&#xff0c;类似无反映&#xff0c;内存报错等…

《计算机组成原理》唐朔飞 第10章 控制单元的设计 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习计算机组成原理时的个人笔记&#xff0c;分享出来与大家学习交流。使用教材为唐朔飞第3版&#xff0c;笔记目录大体与教材相同。 网课 计算机组成原理&#xff08;哈工大刘宏伟&#xff09;135讲&#xff08;全&#xff09;高清_…

反反爬技术,破解猫眼网加密数字

From&#xff1a;https://blog.csdn.net/qq_31032181/article/details/79153578 From&#xff1a;http://www.freebuf.com/news/140965.html 利用自定义web-font实现数据防采集&#xff1a;http://blog.csdn.net/fdipzone/article/details/68166388 利用前端字体文件(.ttf)混…

《这是全网最硬核redis总结,谁赞成,谁反对?》六万字大合集

我摊牌了&#xff0c;这篇文章&#xff0c;值得99%的人收藏 此文后续会改为粉丝可见&#xff0c;所以喜欢的请提前关注和收藏&#xff0c;不迷路。 最近有五本我喜欢的redis实体新书&#xff0c;想要的去评论&#xff0c;我写个随机数抽奖包邮送给你。 那么&#xff0c;准备好…

如何实现第一个单片机裸机程序(附汇编指令)

一、(8-2) 一个芯片上面有片内SRAM内存(4K)&#xff0c;NOR Flash(2M) , Nand控制器(256M)&#xff0c;GPIO控制器 启动过程&#xff1a;(大多数ARM芯片从0地址启动) 1、NOR 启动&#xff0c; NOR Flash基址为0 CPU读取NOR上第一个指令(前4字节)执行&#xff0c;CPU继续读取其…

程序是怎样跑起来的

1. 对程序来说CPU是什么 问题&#xff1a; 程序是什么&#xff1f; 指示计算机每一步动作的一组指令程序是由什么组成的&#xff1f; 指令和数据什么是机器语言&#xff1f; CPU可以直接识别并使用的语言正在运行的程序存储在什么位置&#xff1f; 内存什么是内存地址&#x…

深入理解《hello world》是如何实现的

函数栈桢的创建和销毁 前言C语言是由函数构成的栈帧概念寄存器hello world是如何实现我们转到汇编代码&#x1f333; main函数栈帧的创建(开始调用main函数)&#x1f333; main函数栈帧的初始化&#x1f333;函数栈帧的销毁printf函数栈帧的销毁main函数的栈帧销毁 总结 ❤️ &…

【供应链架构day8】履约系统的架构长什么样子:从需求开始讲起

很多公司&#xff0c;除了自营商城以外&#xff0c;还有其它渠道&#xff08;如天猫、京东等&#xff09;&#xff0c;多个渠道的订单该如何集中履约&#xff1f;订单履约全流程是怎样的&#xff1f;接着小Q的故事&#xff0c;为您揭晓多平台订单履约系统的系统设计思路。 由于…

金融反欺诈-交易基础介绍

一、简介 如今&#xff0c;互联网金融比较火热&#xff0c;金融欺诈也变得非常普遍&#xff0c;金融反欺诈也应运而生。本文将主要介绍下金融交易中的一些基本内容&#xff0c;并简单介绍下历史悠久的并且还未淘汰的磁条卡的风险&#xff0c;这些也是了解金融欺诈需要的基本知识…

详解反调试技术

反调试技术&#xff0c;恶意代码用它识别是否被调试&#xff0c;或者让调试器失效。恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作&#xff0c;因此他们使用反调试技术尽可能地延长恶意代码的分析时间。为了阻止调试器的分析&#xff0c;当恶意代码意识到自…

stl文件的解析和在线3d打印

什么是stl文件 STL(Stereolithography)文件&#xff0c;由3D Systems于1987年创建&#xff0c;并且已被广泛用作全行业3D打印机模型的标准文件。它有一些别的首字母缩写词如“标准三角语言(Standard Triangle Language)”&#xff0c;“标准曲面细分语言(Standard Tessellatio…

\r \r\n \t的区别,是什么意思

分享一下我老师大神的人工智能教程吧。零基础&#xff0c;通俗易懂&#xff01;风趣幽默&#xff01;http://www.captainbed.net/ 也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01; \n 软回车&#xff1a; 在Windo…

著名的 P=NP 问题到底是什么?

△点击上方“Python猫”关注 &#xff0c;回复“1”领取电子书 大家好&#xff0c;我是猫哥。我最近在追一部热播的电视剧《天才基本法》&#xff0c;它反复提到了“PNP”问题。这可是一个天大的难题&#xff0c;在 2000 年克雷数学研究所公布的千禧年七大数学难题中&#xff0…

PCIe 是什么 ? -- 基本知识

1. 概述 1&#xff09;PCIe(Peripheral Component Interconnect Express)是继ISA和PCI总线之后的第三代I/O总线。一般翻译为周边设备高速连接标准。 2&#xff09;PCIe协议是一种端对端的互连协议&#xff0c;提供了高速传输带宽的解决方案。目前PCIe已经发展到第四代PCIe4.0, …