Install a git server use gitolite over the ssh

闲话

最近这段时间处在封闭开发状态,基本上没什么时间写日志了,不过现在也忙的差不多了,更重要的是,今天需要安装一台Git服务器做为开发之用,而且需要把安装过程整理出一份文档 ,所以,咱就直接写出来,也做为一篇日志发布了吧。

进入正题

建立服务器的软件我这里选用Gitolite,之所以选用Gitolite,一是因为之前曾经使用过Gitolite,再一个是因为Gitolite可配置性更高,而且更为小巧。而且,由于这个服务器只在内部使用,没有必要使用Gitlab这种体积庞大的提供过多的WEB方面功能的程序。

没有特别声明的都为在服务器上执行

  1. Git > 使用系统命令安装git客户端,比如yum install git,版本最好不要太低,1.7以上。
  2. 建立Git帐户 > useradd -d /opt/git -m git,用户目录的位置不做要求,但是由于是专用帐号,最好是放在有备份保证的目录,便于管理。
  3. 生成管理公钥 (管理端) > ssh-keygen -t rsa -C "Git Admin" -f gitadmin > 这个步骤需要注意的是生成密钥对最好不要加密码,否则有可能出现奇怪的问题。完成这一步后将gitadmin.pub文件传至git的HOME目录中备用。
  4. 同步Gitolite代码 > git clone https://github.com/sitaramc/gitolite,此命令需要在Git用户的HOME目录中执行。
  5. 安装Gitolite > 在用户目录中执行gitolite/install -ln,参数的意思是在$HOME/bin目录中建立指向源代码目录的文件链接,这样做的好处是可以方便的升级gitolite,另外,install命令另一个参数是-to可以指定命令安装到的目录,默认情况下不需要指定。 > 需要注意的是,默认安装的时候需要将$HOME/bin加入$PATH,如果指定安装目标需要将$HOME/todir加入$PATH。 > 执行完install之后需要执行gitolite setup -pk gitadmin.pub。 > 完成后,需要再检查一下~/.ssh目录和其中的authorizedkeys文件的权限,需要将权限控制为仅本人可读写。
  6. 同步管理库(管理端) > 由于管理端或客户端与Git服务器之间的通讯是基于ssh的,所以,为了便于使用,需要对与Git服务器的连接进行单独配置,打开~/.ssh/config,在其中加入单独定义管理时所使用的密钥文件。

host gitadmin

HostName xxx.xxx.xxx.xxx

User git

IdentityFile ~/.ssh/gitadmin

经过以上配置即可以执行git clone gitadmin:gitadmin获取管理库,之后所有对服务器的管理只能通过此管理库进行,严禁直接在服务器上对服务器进行修改。 7. 修改Gitolite配置及用户管理 详细使用配置及管理方法请参考源代码目录下的README.txt 8. 从Subversion向Git做版本迁移 两种方法 * git svn clone svn://url.to.svn/repos --no-metadata --authors-file=users.txt 直接从svn版本库中clone数据到本地,其中 --no-metadata 指定命令不在git版本库中加入svn版本元数据。 --authors-file 指定与svn用户相对应的git用户。

  • git svn init svn://url.to.svn/repos --no-metadata
  • git svn fetch --authors-file=users.txt 这两个命令为一组,第一个命令初始化一个基于svn源的git库,此时可以在该库的.git目录下修改branches和tags信息,完成之后使用第二个命令开始同步代码,此时代码将按照配置把不同分支或标签下的代码提交到git库的指定位置。 如要迁移的Subversion版本库使用遵循惯例的目录设置,则可以在第一种方法和第二种方法的第一条命令中加入-s选项,本选择可以简化同步的操作。

Windows版客户端TortoiseGit下载地址:http://download.tortoisegit.org/tgit/1.8.8.0/

结束语

Git的使用入门很容易 ,只需要简单的分支、标签管理和版本提交,基本上就可以满足日常的需求,当然,还有更多的特性需要在使用的过程中逐渐的接触和应用。

Get a TexturePacker free license

闲话几句

昨天跟老婆吵了几句,当时确实是非常气愤,不过现在想想真的很划不来,气大伤身不说,昨天也因为这吵架导致了始终静不下心来学习,所以说,这吵架不仅伤身、伤心情,还浪费了时间。 其实本来也没有什么大不了的事情,没有必要非得争个是非黑白,如果确实觉得对方做的不合适,完全可以在对方心情恢复正常之后再换个角度讲给她听,这样在达到目的的同时也避免了伤和气。基本上应该有这个原则,在对方情绪激动的时候最好是避免正面的意见冲突,这不光是在两口子之间的相处之道,在和任何人相处时都是适用的。

说点正题

Texture Packer是一个非常方便的Sprite Sheet生成工具,我在About Sprite Sheet一文中讲到过,那天我在写博文时就发现下面提示还有两天的试用期,于是去到官网上准备,然后就看到下面有个可以申请免费License的链接,看里面的说明,我的博客是符合条件的,于是就试着申请了一下,没想到今天就收到了作者发来的邮件。 Email 同时,下面还附送了一个Physics Editor的授权文件,这个软件我也安装上了,看起来也是非常的强大,尽管我还没有试用,不过我想这对我学习游戏开发的过程一定会很有帮助,在此对作者表示剧烈的感谢。

结语

我想作者愿意为做技术的或跟此相关的人提供免费的授权,一方面是希望能帮助宣传这他的软件以使他能够获得更多的回报,另一方面也是希望他的用户更多,即便是没有得到金钱上的回报,但是由此带来的巨大成就感也是所有软件开发者内心所渴望的。 就像王爷他老人家现在每天熬夜加班费劲巴力的花大量的时间在搞他的一个EF English辅助APP一样,他也没指望能在这个APP上获得什么经济回报,当然能得到经济回报更好,就算得不到,一旦用户多了,我想他也会忍不住请我动吃大吃一顿来庆祝一番的。【千里传音:我说的对吧,王爷?】。

About Sprite Sheet And Tools

闲话

感冒好像有些更严重了,头很不舒服。

下午听王爷说他们发奖金了,虽然不多,但是也是要恭喜一下的,毕竟不管发多少,总比不发强吧,而且现在他的项目进展的也算是顺利。一想到这项目还是会有些郁闷,毕竟是我们哥几个一点点弄出来的,现在却成了别人的孩子,而且还是不太待见的孩子,郁闷。

正文

今天随便说说Sprite Sheet吧,简单来说,这是一个小图片集合。我印象中,这种技术最早用于WEB开发中,当在网页中使用很多小图片时,在访问时,浏览器需要对每个图片发起请求,而每次请求都只传送了一个很小的图片文件,这无形中就浪费了大量的HTTP请求和网络连接,即使在HTTP 1.1的环境中,默认的头Connection保持keep-alive时可以我重用连接,便是多次请求传送的Header也会浪费很多的流量。

因此,就有聪明人发明了这种方式,把多个小图片合成一个大图片,这样不仅减少了请求数、节约了资源,还使数据传输更加有效率,于是人们亲切的称之为Sprite Sheet。

而在游戏开发中,合理的使用Sprite Sheet同样有着积极的作用,比如将相关性较高的图片合并到一张大图片中,不仅可以使图片的渲染过程得到优化,同时还能使图片资源更便于管理(这也是我最近也学到的,:))。

<!-- more -->

相关工具

最早的时候,我也曾经做过WEB开发,那时候比较笨,也可以是当时没有发现更好用的工具,我一般是直接使用Photoshop或Firework进行拼图,同时记下每张小图片的坐标,在使用的时候将这些坐标用在CSS中获取相应的小图片,这种方法相当相当的麻烦,后来就因为这个原因我就索性不再自己做这件事了。

之后的发展我就没有见证过,因为那时候我已经离开了WEB开发这一行,而直接进入了游戏后端开发,在游戏后端开发中用不着这类的知识。直到最近,我开始学一些游戏开发的知识,这才又一次接触到Sprite Sheet

首先接触到的工具是Zwoptex,这个工具用起来也算是比较方便,简单说一下其用法。

  1. 打开zwoptex,将图片拖入其中。 Zwoptex图1
  2. 点击工具栏中Layout。 Zwoptex图2
  3. 调整图片大小。
  4. 重复2、3步,直到图片大小合适,并能够将其中小图片正确显示。
  5. 点击File - Publish Settings,并设置。
  6. 点击Toolbar中的Publish,导出文件。

在使用中,这个工具可以满足一般需求,并且在导出图片时支持同时导出.plist文件,这在Cocos2D和Cocos2D-X开发中用起来自然是极方便的,更重要的是,这个软件不注册也可以一直使用,唯一的不爽就是会有弹窗3秒倒计时,虽然不爽,但是倒也是可以接受的。

在说另一个工具 Texture Packer,这是我的一个朋友介绍给我的,这也是个收费软件,而且,如果不购买就只能试用7天,嗯,虽然时间不多,但是也足以让你体会到这个软件的方便之处了。

以下是使用方法:

  1. 打开Texture Packer,并将图片拖入其中。 Texture Packer图1 当图片拖入程序的一瞬间你会发现,图片已经排列好了,而且所占用的空间也是最小的。 Texture Packer图2
  2. 在右侧Data Format中选择需要的格式,然后点击Toolbar中的Publish。
  3. 没有第三步了。

到此,这两个工具就说明完毕了,当然了,我在这里说的并不是全部,每个工具都有很多可以设置的选项,这个需要根据需要自己进行研究了。

我之所以拿这两个工具进行说明,最主要还是因为,目前为止我就只接触到这两个跟Sprite Sheet相关的工具,而且两个都很好用。当然了,如果是我选择一个,我肯定会选Texture Packer,其原因是,这个工具支持的导出格式更多,而且在导入图片时就自动对图片进行最优的排列,并进行适当的翻转,以求能使其占用的空间更小一些。而Zwoptex在自动化方面就差了一些,需要自行调整画布尺寸,而且,在排列图片时就显得比较死板。

另外,Texture Packer在导入图片时可以选择导入文件夹,这一点Zwoptex是无法做到的,同时,Texture Packer导出的图片也较后者稍小,例如我在使用中生成的图片,前者生成的图片171K,后者生成的为180K。

结束

本文只是对这两个软件进行简单的测试、比较,结论也属于个人观感,这只是为自己选择软件提供一个依据。

Cocos2D-X learning 4

废话

今天和王爷一起去传说中的车库咖啡见了一个创业团队,跟他们有了一个小时左右的交流时间,交流的详情就不说了,总之,让我和王爷多了一个很好的话题,在回家的路上,我们就这个话题进行了友好、亲切而又愉快的交流,受益匪浅。 不过,最糟心的是,跑这一趟我竟然感冒了,主要是天气热,出了很多汗,而在地铁通道里风太大,晾了汗了,纠结死我了,明天还要去见一个离得比较近的创业团队,我在犹豫到底还要不要去。

概述

今天随便说说在Cocos2D-X开发中,关于对CCSprite方面的优化,总得来说就是尽可能减少渲染次数,这样可以使游戏运行更有效率,能够空出更多的CPU时间做其它的事情,以增加游戏的流畅与体验。

正文

Cocos2D为图片资源批量加载提供了CCSpriteFrameCache类,此类可以通过使用Sprite Sheet文件来减少图片加载次数,简单来说,就是把多个图片拼成一个大图片,之后通过坐标在大文件上取到相应的图片,这个技术被广泛使用在网页设计及游戏开发中。在这里我使用了一个叫做Zwoptex的软件自动生成大图片及相应的.plist,软件的具体使用方法就不在这里细说了(另外,朋友介绍说Texture Packer是可以更好的做这件事的工具,改天尝试一下)。

另外,Cocos2D还提供了一个CCSpriteBatchNode类,这个类主要作用是,当相同图片资源被重复使用时,通过这个类可以减少使相同的图片只渲染一次,具体做法看下面的代码。 PS: 代码基于上一篇BLOG,只对关键部分进行说明。 <notextile>0</notextile>

<!-- more --> <notextile>1</notextile>

以上代码中,第25-29行为游戏添加了背景,这个不在本文的写作目的之中,其中27、28行是将背景的大小和位置调整到铺满整个窗口。 第31、32行利用.plist文件初始化了一个SpriteSheet图片,CCSpriteFrameCache类全局有效以单例的形式使用,但是为了方便后面使用,这里单独声明了一个CCSpriteFrameCache对象。 从34行开始到第40行,声明一组CCSpriteFrame对象,并通过文件名在CCSpriteFrameCache类中初始化。从49行到66行,通过已经创建的CCSpriteFrame对象创建一些相应的CCSprite`实例,并做位置做相应的调整后加入到场景中。 在这里为了便于说明,尽可能少的牵涉到无关内容,对代码本身并没做优化。 进行CCSpriteBatchNode优化前 注意看界面左下角的帧率信息。

下面,我们在代码中通过CCSpriteBatchNode对程序进行优化,代码如下: <notextile>2</notextile>

代码中,第33-34行,创建了一个CCSpriteBatchNode对象,并将其加入场景,在51-68行中,所有的CCSprite对象全部加入到CCSpriteBatchNode对象,此时,所有的CCSprite将不再重新渲染,如下图: 经过CCSpriteBatchNode优化后 与之前的截图相比,渲染次数减少到2,说明这样的优化方法是可行的。

说明:CCSprite对象必须加入到CCSpriteBatchNode中才能起到优化作用,如果直接将CCSprite加入到场景中,则不会重用CCSpriteBatchNode的渲染结果。这里可以理解为,CCSpriteBatchNode是一个虚拟的容器,将此容器加入到场景后,再将CCSprite加入其中,由CCSpriteBatchNode对其进行管理,另外,如果CCSprite使用的资源不包含在CCSpriteBatchNode初始化的资源中,则程序会出现异常。

结束

程序的优化方法有很多种,但是并不是所有的优化方法都适用于当前的应用场景 ,这也牵涉到优化的性价比的问题,对程序进行适度的优化才是最正确的。

另:由于本人是初学跟前端有关的开发,特别是游戏前端,因此,在我所讨论的内容中难免有所偏颇,希望能够得到大家的指正,谢谢。

Cocos2D-X learning 3 (CCScene and CCMenu)

废话

本来部门计划今天下午全部门去搞团建的,主要活动是开卡丁车、桌游等项目,可惜天不从人愿,早晨有点下雨,好不容易盼到中午晴天,结果Leader又一个通知,说今天事情太多,活动改期到下周了,我勒个去的,废话不多说,进去正题。

概述

今天练习的内容主要是在Cocos2D开发中,对菜单的运用以及场景切换,中间还涉及到对于CCSprite对象的一些操作和schedule的简单应用。

正文

首先用create_project.py建立一个基础项目,然后分别建立两个CCLayer的子类。 <notextile>0</notextile>

这是一个最简单的头文件,相比上一篇只多了一个私有方法void onStartClick(CCObject *obj),其作用后面再说明。 <!-- more --> <notextile>1</notextile>

以上代码生成场景如下 场景1

StudyCocos2D::init()方法中完成了建立,菜单项的工作,使用CCMenuItemFont类建立一个基于文字的菜单,在CCMenuItemFont::create(const char *, CCObject, selector)方法中完成了一个文字菜单项的建立,第一个参数是显示在菜单中的文字,第二个参数是作用于哪一个对象,第三个则是指定响应触发动作的方法。 void StudyCocos2D::onStartClick(CCObject *obj)方法完成了点击菜单后的操作,首先建立从RotatingIcon类中创建一个场景,然后用CCDirector::replaceScene(CCScene *)方法将显示的场景替换成新的场景。 iconScene->autorelease()方法的调用,会使本场景不在使用时自动释放。 <notextile>2</notextile>

<notextile>3</notextile>

场景2 这里声明并定义了RotatingIcon类,在此类中需要说明的是,在Cocos2D中,精灵的锚点在该精灵的中心,如一个包含图片的CCSprite对象,在没有明确设置锚点及坐标时,会显示在场景的左下角,且只显示四分之一,因此,对于精灵对象一般都需要明确指定其坐标。 在以上的代码中,使用CCDirector::getWinSize()得到游戏显示区域的大小,之后就可以在下面的ccp(winSize.width/2, winSize.height/2)中计算出场景的中心,经过此设置后,图片将显示在整个场景的中心,其中ccp(__X__, __Y__)是一个宏,这个宏可以用来产生一个CCPoint对象。 schedule定义了一个执行计划,在以上代码中的调用方式,可以在程序在每一帧都执行一次指定的方法。 在void RotatingIcon::rotatingIcon(float t)方法中,程序首先获取当前场景的子元素,此调用将返回一个CCArray对象。在获取到第一个子元素后,直接对该元素的旋转角度进行加1的操作,以实现图标不间断旋转的功能。

最后,在AppDelegate.cpp文件中,将建立场景的那一行代码修改为CCScene *pScene = StudyCocos2D::scene();

结束

今天练习的内容非常简单,就是实现了菜单、场景切换和图标定位及旋转的功能,这些都是基础的概念和元素,需要很好的掌握其用法。

关于MySQL网络协议中的数据包序号

对MySQL协议稍作了解后,我们就知道在协议中,服务端与客户端相互之间的通讯都是以包的形式进行的。

在这些包中,有一个固定的特征就是前四个字节用途不变,前三个字节表示数据包的长度,第四个字节表示当前包在本次交互中是序数。

前三个字节最大只能表达16M的长度,这是三个字节表达无符号整型的极限,所以,每次客户端可以接受到的最大数据包为16M+4个字节。

至于第四个字节,这是表达当前包的序数的,一个字节能表达的最大正整数是255。我们知道,在MySQL协议中,发送COM_QUERY命令后,服务器返回的数据格式为,响应头为一个包,然后,每一个字段的描述也会是一个包,字段说明后面会跟一个EOF包表示字段描述结束,之后则跟随的是表中的数据,每一个数据包表达一行数据,一般情况,我们每次从数据库里检索的条数,去掉描述协议的部分,在序数中我们还有不少空间可以用在数据记录上,但是,如果总的包数超过255,那会是怎么的情况哪?

在我们使用数据库的经验中,我们可以经常有机会看到很多条记录同时显示出来的例子,记录数明明超过了255,可是依然正常显示,这是为什么哪?

经过对MySQL交互嗅探,我发现在数据包次序达到255后,之后紧随的包的次序就变成了0,在Wireshark的协议分析中会认为这是错乱的协议,我想,这应该是MySQL特意使用的方式。

前后端的交互中,到发现次序达到255后,对序数加1,由于只使用了一个字节,所以数据溢出变成了0,这样的情况在MySQL协议中被认为是合法的,只要前后端认可这种方式,那这种通讯就不会出错。

所以我认为,在MySQL通讯中,包序号只是用来确认包的次序没有发生错误的,至于序号是几并不重要,只要认定255号后为0号是合法的,那就可以达到正常交互并保证数据序号不会出错的目的。