这周开始又转回了熟悉而又陌生的Unity开发,一年前从Unity转向cocos2dx,这一年里有不少曲折,也有不少的心酸,或许是因为“心”未定,又或许因为其他,有种使不上劲的感觉,曾经的傲气逐渐的被“驱散”,习惯了被训斥和教育。面的各种形形色色的技术,总是经不住诱惑,都想学习一遍,但又无奈精力有限,加上工作的压力,每天都搞的身心疲惫,总之这一年里对自己的评价用“失望”两个字来形容!但从这周开始又重回Unity开发,心里有一丝喜感,或许真的对它期待已久!昨晚看着游戏蛮牛上一些老大们写的关于Unity的技术分享的文章,直到一点还依然没有睡意,深深的陶醉了,迫于第二天要工作的压力才不得不依依不舍的关闭电脑睡觉。接到先前公司的老板的一个需求,他们用Unity做的应用软件,有一个需求:用二维码作为应用激活密钥,一个二维码能激活五台设备,当激活设备数目大于5该密钥失效。鉴于之前老板先前待我还可以,就当还个人情,帮他完成该需求。先前做过Unity的扫码的客户端,也有记录过相关文章(http://blog.csdn.net/dingxiaowei2013/article/details/25086835)。这里就简单记录一下开发流程。
一、数据库表的设计
canbeuse bool值标记该二维码密钥是否失效,当然我下面T-SQL写的逻辑是当该密钥失效直接删除该密钥信息,所以该字段就没多大意义,以备有需要时使用!
二、存储过程(T-SQL)设计
-------------------校验qrcode是否可用存储过程---------------------------------- alter PROCEDURE searchproc @qrcodetext nvarchar(50), @result bit output AS begin declare @count int, @selectrows int select * from dbo.QRCodeTB where qrcodetext = @qrcodetext; set @selectrows = @@ROWCOUNT if @selectrows > 0 begin select @count = cast(usednum as int) from dbo.QRCodeTB where qrcodetext = @qrcodetext; if @count < 5 begin set @count = @count + 1 update dbo.QRCodeTB set usednum = @count where qrcodetext = @qrcodetext set @result = 1 end else begin --update dbo.QRCodeTB set canbeuse = 0 where qrcodetext = @qrcodetext delete from dbo.QRCodeTB where qrcodetext = @qrcodetext set @result=0 end end else begin set @result = 0 end end GO -----------------------------执行验证------------------------------------- declare @result bit exec searchproc 'ED81D6FF-86A3-49C1-BF40-1A05521803DC',@result output; select @result select * from dbo.QRCodeTB --------------------------------添加记录存储过程-------------------- alter PROCEDURE insertoneinfoproc @num int, @count int output AS begin while @num > 0 begin insert into dbo.QRCodeTB(qrcodetext,canbeuse,usednum) values(NEWID(),1,0) set @num = @num - 1 end set @count = @@ROWCOUNT end go declare @count int exec insertoneinfoproc 1,@count output ; select @count; select * from dbo.QRCodeTB -------------------------添加数据-------------------------------------------------- insert into dbo.QRCodeTB(qrcodetext,canbeuse,usednum) values(NEWID(),1,0) -------------------------查询数据------------------------------------------ select * from dbo.QRCodeTB -------------------------清空数据表-------------------------------------- Truncate Table dbo.QRCodeTB存储过程执行结果:
连续运行五次之后:
显示该密钥不可使用。貌似之前都一直没尝试过写T-QSL,这也算我第一次尝试写这么长的sql,在大神眼里这太小菜了哈!
web端设计
web采用的是.net一般处理程序
1.webconfig数据库信息配置
2.简单的sqlhelper类
using System.Configuration; using System.Data; using System.Data.SqlClient; namespace SQLHelper { class SQLHelper { private static readonly string connectstr = ConfigurationManager.ConnectionStrings["SqlConnStr"].ConnectionString; public static SqlConnection CreateConnection() { SqlConnection conn = new SqlConnection(connectstr); conn.Open(); return conn; } public static int ExecuteNonQuery(SqlConnection conn, string sql, params SqlParameter[] parameters) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } public static int ExecuteNonQuery(string sql,params SqlParameter[] parameters) { using (SqlConnection conn = CreateConnection()) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } } public static int ExecuteNonQuery(string sql, CommandType type, params SqlParameter[] parameters) { using (SqlConnection conn = CreateConnection()) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.CommandType = type; cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } } /// <summary> /// 执行带输入输出参数的存储过程 /// </summary> /// <returns></returns> public static string ExecuteNonQuery(string procname, int outputindex, params SqlParameter[] parameters) { using (SqlConnection conn = CreateConnection()) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = procname; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddRange(parameters); int executeEffectNum = cmd.ExecuteNonQuery(); return parameters[outputindex].Value.ToString(); //返回第一个输出参数 } } } public static object ExecuteScalar(SqlConnection conn, string sql, params SqlParameter[] parameters) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); return cmd.ExecuteScalar(); } } public static object ExecuteScalar(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = CreateConnection()) { return ExecuteScalar(conn, sql, parameters); } } public static DataTable ExecuteQuery(SqlConnection conn, string sql, params SqlParameter[] parameters) { DataTable table = new DataTable(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); using (SqlDataReader reader = cmd.ExecuteReader()) { table.Load(reader); } return table; } } public static DataTable ExecuteQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = CreateConnection()) { return ExecuteQuery(conn, sql, parameters); } } } }
3.二维码生成
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using SQLHelper; using System.Data; using System.Data.SqlClient; using ThoughtWorks.QRCode.Codec; using System.IO; using System.Text; namespace WebApplication { public partial class CreateQRCode : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } /// <summary> /// 创建一个二维码密钥 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void CraeteQRCodeBtn_Click(object sender, EventArgs e) { string path = Server.MapPath("~/images" + "//qrpngfile"); string name = "QRCode"; //创建文件夹 Directory.CreateDirectory(path); string sql = "select top 1 qrcodetext from dbo.QRCodeTB"; string qrcode = SQLHelper.SQLHelper.ExecuteScalar(sql).ToString(); if (!string.IsNullOrEmpty(qrcode) && !createImage(qrcode, path, name)) { Label1.Text = name + "已经存在"; } } /// <summary> /// 向数据库添加一条二维码记录 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void CreateUIDBtn_Click(object sender, EventArgs e) { int num = 1; SqlParameter[] paras ={ new SqlParameter("@num",SqlDbType.Int,1){ Value=1 }, new SqlParameter("@count", SqlDbType.Int), }; paras[1].Direction = ParameterDirection.Output; this.Label1.Text = "开始执行"; int rowseffect = SQLHelper.SQLHelper.ExecuteNonQuery("insertoneinfoproc", CommandType.StoredProcedure, paras); if (rowseffect > 0) this.Label1.Text = "插入成功"; else this.Label1.Text = "插入失败"; } #region 生成二维码 /// <summary> /// 生成二维码 /// </summary> /// <param name="path">地址</param> /// <param name="name">图片名称</param> /// <returns>bool</returns> public bool createImage(string value, string path, string name) { QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); //设置背景颜色 //qrCodeEncoder.QRCodeBackgroundColor = Color.FromArgb(255, 255, 0); //设置前景色 //qrCodeEncoder.QRCodeForegroundColor = Color.GreenYellow; //编码格式 qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; //设置每个二维码像素点的大小 qrCodeEncoder.QRCodeScale = 4; //QR码版本 //QR码所允许规格系列为21×21模块(版本1)~177×177模块(版本40) qrCodeEncoder.QRCodeVersion = 8; //纠错等级 //level L : 最大 7% 的错误能够被纠正; //level M : 最大 15% 的错误能够被纠正; //level Q : 最大 25% 的错误能够被纠正; //level H : 最大 30% 的错误能够被纠正; qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; //自定义的二维码数据 String data = value; //Response.Write(data); //画图 System.Drawing.Bitmap image = qrCodeEncoder.Encode(data); System.IO.MemoryStream MStream = new System.IO.MemoryStream(); image.Save(MStream, System.Drawing.Imaging.ImageFormat.Png); //Response.ClearContent(); Response.ContentType = "image/Png"; //写图片到页面 Response.BinaryWrite(MStream.ToArray()); path = path + "\\" + name + ".png"; if (!File.Exists(path)) { FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite); BinaryWriter bw = new BinaryWriter(fs, UTF8Encoding.UTF8); byte[] by = MStream.ToArray(); for (int i = 0; i < MStream.ToArray().Length; i++) bw.Write(by[i]); fs.Close(); return true; } else return false; } #endregion } }
4.二维码验证
这里采用的是get请求方式,方便测试,安全起见最好用post请求
using System.Data; using System.Data.SqlClient; using System.Web; namespace WebApplication { /// <summary> /// CheckCode 的摘要说明 /// </summary> public class CheckCode : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //context.Request.Form["codetext"];//post string codetext = context.Request.QueryString["codetext"]; //get if (codetext != null) { SqlParameter[] parameters = { new SqlParameter("@qrcodetext", SqlDbType.NVarChar,50), new SqlParameter("@result", SqlDbType.Bit), }; parameters[0].Value = codetext; parameters[1].Direction = ParameterDirection.Output; int outputindex = 1; string resNum = SQLHelper.SQLHelper.ExecuteNonQuery("searchproc", outputindex, parameters); context.Response.Write(resNum); } else { context.Response.Write("没有输入二维码信息"); } } public bool IsReusable { get { return false; } } } }
web验证
当密钥使用五次之后,返回给客户端的是false结果,也就是密钥已失效,同事服务器做的就是从数据库表中删除带密钥信息!
关于Unity扫码客户端的就不记录了,之前有过相关记载,就主要用到www提交表单,还有扫码插件制作(请看下面相关连接有记载),其他就没啥了。天色已晚,承诺某人今天早点睡的,貌似又食言了,sorry!貌似这两周都睡的比较晚,明天周末了,好好补一觉!
相关连接:
C#/.NET存储过程:http://www.cnblogs.com/clhed/articles/1269415.html
扫描二维码客户端:http://blog.csdn.net/dingxiaowei2013/article/details/25086835
Unity跟服务器交互(表单提交):http://blog.csdn.net/dingxiaowei2013/article/details/17115489
Unity客户端效果:
==================== 迂者 丁小未 CSDN博客专栏=================
MyBlog:http://blog.csdn.net/dingxiaowei2013 MyQQ:1213250243
Unity QQ群:375151422 cocos2dx QQ群:280818155
====================== 相互学习,共同进步 ===================