盗賊の極意

Feed Rss

沉迷CnBeta的人应该都看到过那个昆明loser程序员(以下简称昆明)的留言吧,几乎在每篇新闻的留言区里都能看到的那个,伤感的故事。。。

昆明的故事背景,可以参考这篇文章

我看得挺无力的。

很久以前,国内有一部很有名的电视剧叫做《蜗居》,故事中讲到一个单纯的loser程序员被高帅富NTR后选择了默默退出。今天的昆明,和那时的莫小贝有点像。

程序员好像工匠,最重要的是手艺,创造什么的也是靠之前掌握到的手艺和知识搭建起来的。这有点像做数学题,比高中生做的复杂,但远没有理科生和研究生院搞得学问深奥……哎呀,怎么有点说不清的感觉呢

这样吧,程序好像做数独,做逻辑思考题,我总想找些更难、但我又做得出来的题,从做题的过程到完成后的成就感,都是享受。做题的过程中,我的能力在提高,我做得出来的题的上限在被拉高,所以能取悦到我的工作也越来越有分量,越来越有价值。这样,经过一段时间不断的工作,我的个人能力得到了提升,我的价值也随之升高了,而且这期间我还玩得很尽兴——这是我心目中的程序员升级之路。沿着这条路走下去就是我的程序梦想。当然工作上不会总是给我刚刚好的工作,所以课余时间的自娱自乐就很重要了。

明明是这么快乐的路,这么明亮的前程,为什么真的干上这一行的前辈们却都喜欢自嘲,总是看起来很愤怒、很消沉呢。因为待遇不够高吗?嗯,这真的是个问题。即使是学生的我,在高薪的工作机会面前也很犹豫。我跑去参加过高薪的咨询行业的实习,万幸,被刷了。当时他们给的应届生年薪真的是充满了诱惑力啊,但工作内容确实不适合我。比起“说服”(有点像忽悠?),我还是更喜欢我的数独和逻辑题。到底有多喜欢呢?这么说吧,有一次我在研究室听日本的学生谈到他们的金融界前辈,30多岁年薪1亿-3亿,我彻底崩溃了——有这收入,叫我干啥都行啊!!!!! 咳咳,可见,我对我的逻辑题的喜欢程度,在这个数字之下呢

那些不满自己程序员工作的前辈们,对这个行业的喜欢程度可能也不是很高吧,大概在一个“早知道XXX行业那么赚钱,我才不当什么程序员呢”的程度。我相信,这就是我未来不会落入同样失落状态的有力证据。因为我喜欢我选择的工作(我是未来的游戏程序员!!!),喜欢到另一份无趣行业的工作有哪怕三倍、五倍、十倍的薪水,也不会影响我和它的感情的程度。嘛,这和我的起薪很低也有一定的关系。这个薪水,三倍了也不会很了不起……

果然追妹纸不应该拼收入,应该拼人品啊!!

标题原本想起《某弹幕视频网站(B站)站长高姿态讽刺视频投稿者的存在价值,致使用户“自杀”》的,这也是我对本次事件的理解。客观描述可以看和谐社的『UP主的革命-B站UP主集体删档事件

从聊天记录里可以看到B站站长当时说话有多狠,不仅在导火索事件上怪罪搬运者们,甚至直接抹杀了他们的存在价值。B站站长在事后的公开道歉文章中说他自己当年也是UP主,深知视频“制作压制的不易”,言外似乎还是不愿意承认“搬运”的价值。

搬运本来就没有原创来得伟大,正如这位站长所说,视频很快就能补回来,损失转眼就会被人遗忘。但是,在这次事件中,我还是选择了站在搬运者一边。

搬运这事有点像画画里的临摹:这活儿本身没有任何创造性,但还是很容易能分得出谁干的漂亮,干得好的人更能给观众带来愉快感受。我支持搬运者,很大程度上因为我是一个临摹爱好者,我想主张我们的存在价值。

以下省略……

附录:

黎大小姐为什么这么在意被抢走的little busters -> http://tieba.baidu.com/p/1882332235  (注意,这是在事发前三周发的帖子,而不是事后找借口)

有比较全面的当时的QQ群聊天内容截图-> http://blog.sina.com.cn/s/blog_67e1e22101017e8c.html 那种感觉真的有点像,皇上身边围着一群人说您英明,他们都是刁民怎么怎么着的……评论里有人匿名黑黎大小姐,说得我也很火大,我们学生党啊,在小圈子里干点什么事都是无偿什么的早就习惯了,支撑我们的只是你们看来微不足道的“荣誉感”,连这个都不放过,要从我们手里夺走的话,无异于否定了我们的存在价值。遇到这种人也算是个契机,从此放弃小圈子回归现实世界何乐而不为呢。

目前来说,如果你把自己买的cd拷进自己的电脑里给自己听(或者还没来得及听),那么显然你已经触犯了法律(太狠了)。如果碰巧这张cd的著作权所有人不喜欢你,那么你将有机会支付最多200万日元的罚款并处以上至2年的有期徒刑。

把自己玩游戏的过程录下来上传也是违法的,不论你加不加实况解说。

用自己买的动画dvd导入电脑里(违法行为1)作为材料制作MAD视频,又将其上传至视频分享网站(违法行为2),将面临数罪并罚。

在youtube上看某些官方提供的视频时也要小心,看可以,但是如果你用带缓存功能(缓冲好以后离线也可以看)的工具把这个视频缓冲好了的话,你已经走上了犯罪的道路。

VLC之类可以在电脑上播放CD/DVD等介质的开源影音软件将被列入非法软件行列,在线分发这类程序也是犯罪。

==================================================================================

这样的条件,对遵纪守法的日本人来说都称得上苛刻,更何况我这种早已被“共享拯救世界”等概念洗了脑的危险人士。

今天跟家里打电话,聊到马博士,现在想想,他是我们一批人里最踏实的一个了吧。

心态好真的很重要。

想起当年在寝室里看到他查阅色色的网站时,他也没有扭捏掩盖,也没有很中二的假装炫耀,坦然中还略有一点羞涩,真是……好萌啊

漫画啊小说啊什么的拿起来能看进去,这一点我也很佩服。我的话,八成是先搜搜看这书评价如何,然后对比看看有没有其他更好的选择,然后胡思乱想一阵,然后时间就没了。结果马博士成了博览群书的马博士,小把戏还是当年的小把戏

多么励志的马博士!以后我也要本着“多动手少动脑”(正面意义)的踏实作风走下去!

不胡思乱想,以踏实的方式追妹纸!

从java转到C++,不得不自己处理各种头文件包含问题。以前完全没有过这方面的经验,摸石头过河中

事情的背景是这样的:我有一套游戏代码,现在想给它做一个编辑器,希望尽可能重用以前的代码,不要一样的功能复制到两个项目里,以防止一个功能这边修改了那边没修改。

嗯,因为我的设计能力有限,导致要修改很多出才能重用原有代码。这已经不能叫完全的“重用”了吧……嘛,不真正重用这么一次,我永远也不会知道哪里应该设计的更灵活的,算是个好教训吧,好教训。

所谓复用,其实也只是新建一个项目,把原来游戏的源文件都导入进来,然后改一改。

在写编辑器的时候,我发现我需要修改引擎文件engine.h,我不希望这个修改应用于游戏本身,所以我从编辑器项目中移除了游戏的engine.h和engine.cpp文件,然后在编辑器项目目录下新建了两个同名文件导入了项目,在这两个新文件里做我的修改。

一开始我挺紧张的,感觉这么做很不靠谱,这肯定不是正确的复用之道(显然不是)。但是事实上它正确运转了,我也就没再多想。直到刚才,我发现我在engine里新写的函数IDE的自动补全里不给显示,硬写上去就是编译出错。到这里,我第一个想到的就是engine头文件导入错了。事实证明也确实如此。

我想,文件导入的头文件应该是和这个文件在同一个真实目录中的同名文件吧。比如engine.h文件在我的编辑器目录和原来的游戏目录里都有。我先导入了一个原来游戏目录里的头文件比如XXXWidget.h,因为这个头文件里include了engine.h,这个engine.h就是和这个XXXWidget.h在同一目录下的engine.h。哪怕我项目里有一个同名同姓的engine.h,include也是只看相对目录,不看项目配置。

那怎么办呢。

这个问题是我在编辑器目录里写新文件时遇到的,所以我在这个新文件的一排include命令的最后又手动include了一下engine.h(原本是靠前面include的原来游戏项目中的头文件间接include engine.h文件的),无效。我又把include engine.h的命令挪到了间接引入engine.h文件的头文件引用前面,行了。

经典的霰弹枪编程方法= =,再加上以前马博士指出的我的源代码注释陷阱,变量命名方式,看来我还是集各种恶劣的编程习惯于一身了

这时我才突然想起来,engine.h里面有

#ifndef__ENGINE_H__

#define__ENGINE_H__

这两句。所以只有最先被导入的engine才有效。嗯,懂了。可是再一想,那是不是我的项目里有的engine用的是原来的,有的用的是新的啊?这样,会不会有问题?还是一个类只有第一次导入的才有效?我行说ifndef命令啊define命令什么的都是只作用在一个源文件上的,在另一个源文件里就从新算了?嗯,好像接触到了一个比较深的C++问题了呢。一直被java照顾着,完全没考虑过这方面的事情,以后努力补上吧。这次我要优先做完编辑器,遇到的问题先搁置不理它!

#ifndef __ENGINE_H__

我实际执行了一下(做了一些调整),有个很诡异的bug:

如果我加入1个以上的CheckListboxItem的话,最后一个的文字不会显示,而且最后那个文字条无法被选中(如果文字为空的普通Item,虽然看不到字,但是点那里是可以选中Item的),但checkbox却正常显示、正常运转了。

但我再追加一个普通的EntryItem的话,前面的也能正常显示了!

CEGUI太大太复杂,想把它整个包含进来下断点排查对我来说基本上不可能。

在浪费了很多时间以后,我决定阻止自己再在这个bug上浪费时间了。反正知道了可以用空的EntryItem不完美地解决这个问题,之后就以这个不完美的解决方法为基础写我的关卡编辑器吧。

这种事情常常发生(比如这起)——我花了大力气去解决一个疑难杂症,来获得微不足道的提升。其实,如果今后我都没机会用CEGUI了的话,会解决这个bug对我来说也没什么意义。如果今后我还有机会继续研究它的话,到时候再去研究这个bug就好了。以我门都没入的水平想去排查杂乱如迷宫的cegui内部结构,还不如拿那个时间先把编辑器的小样做出来再改进呢。

原文:CEGUI官方wiki

翻译:基拉铃妖

===================================================================

2012.10.15日更新

被这教程坑啦!!!

后来人注意:在“在CEGUI中正确地注册这个窗口”那段代码里,addFalagardWindowMappings的第二个参数应该填你在CheckListboxItem.cpp里初始化的WidgetTypeName的值,在这个例子里就是“CEGUI/CheckListboxItem”,而不是它的基类“CEGUI/ItemEntry”!!填ItemEntry虽然也能运转,但你在CheckListboxItem里重写的基类函数都不会生效.

我昨天就是死活覆盖不了基类函数,后来下断点发现它连我重写的构造函数都没有进入,当时就寒心了啊我去!!!

还我时间!还我被消耗的对CEGUI的热情!!


-----------------------------------------------

不过多亏这个教程我才知道怎么自定义控件,而且它全文也就这一处错误,总的来说还是收益远大于危害的。

……唉。想不违背公允就得好坏都看,这样一来连发泄一下的机会都没有了……

===================================================================

有时候你需要一个列表来包含一些可选中的item。CEGUI 0.5引入的ItemListbox可以接受所有继承自ItemEntry的item。我将向你介绍如何创建一个CheckListboxItem来放入你的list中。

开始!

我假设你使用的是标准imageset,以及标准scheme(现在支持TaharezLook和WindowsLook)。

我们首先来写一个looknfeel entry。这是本教程中最重要的内容,它将占整个教程70%左右的比重。首先,这个entry有几个声明(states):

1.Enabled:当item是enabled时,它是什么样子。

2.Disabled:当item是disabled时,它是什么样子。

3.SelectedEnabled:当item被选中且是enabled时,它是什么样子。

4.SelectedDisabled:当item被选中且是disabled时,它是什么样子。

写下所需文件

打开一个合适的looknfeel文件(WindowsLook.looknfeel或者TaharezLook.looknfeel),然后在文件底部填上以下内容(说是在最下面但是也要在Falagard tag内!)

我们的开始

我们首先需要定义一个WidgetLook,这个文件里包含所有的动作(action)。它有一个属性,name。它代表拟定一个这个widget的名字。现在我们来添加声明(states)。这些声明(states)使item可以响应指定的事件(Events)。比如,当item被设为disabled,则声明(state)Disabled将被使用。

我们通过StateImagery定义一个声明(state)。它需要属性name来指定它在哪个状态(state)内。先不用管Layer。Section总会被用到。这一部分负责市级改变外观。它需要一个属性section,这是要改变 什么 ,在这里指label。TextColour就是颜色(黑色),我们会在下面定义它。现在,如你所见,Enabled状态(state)只是把文本颜色设为黑色,仅此而已。Disabled也类似(记住这是一个item,items通常不会是disabled状态的)。

现在我们来看看另外两个状态。

这些状态很好地解释了它们自己,虽然里面又多了几个section。Section不仅定义要改变什么,它还定义什么应该被显示。在Enabled状态中我们不想让他看起来是被选中的,所以没有selection section。注意,你书写Section的顺序同时也是Z轴的顺序。在本例中我们把selection图放在前面,然后是文字。如果我们把顺序反过来,就看不到字了。(被selection图挡住了)

现在我们来添加颜色和属性的定义。

我们的第一个PropetryDefinition只是定义了一个用在StateImagery sections中的文本颜色。其他PropertyDefinitions也一样,除了SelectionBrush。它不是定义颜色,而是定义了一个图像。在这个例子里,它使用定义在imageset里的WindowsLook的背景图。然后,我们有了一个可以影响某些设置的Property(属性)。在这个例子里,我们通过添加Selectable属性并设为true来创建一个item。

写功能部分

我们现在需要增加增加绘制背景、文字和选取的部分。这看起来有点难,不过其实不是。我们从一个NamedArea开始吧。它是listbox item所必需的,因为listbox需要知道这个item有多大来确保把它很好地放进list。

我假设你知道Area、Dim之类的基本概念。FontDim是用来根据label改变item的尺寸的。我们刚刚加进去的部分定义了item的尺寸。这次我不再贴出全部代码,而只展示新增的部分。

OK!现在我们来添加一个世纪的Checkbox吧。这对我们的目标来说很重要,因为它是我们的item可以被点击选中。我们不用为Checkbox写全部的状态和其他东西,我们直接用Child!只要把下面这段内容放在我们的NamedArea下面、第一个StateImagery的上面即可。(它俩中间)

这里添加了一个WindowsLook/Checkbox到我们的item里面去了。其中的suffix是必需的,加它是为了使name不重复。剩下的内容就非常直白了——把checkbox加到item的左边,和左边界留出3个像素的距离,让它看起来更平整一些。

现在我们需要一个label,这部分很简单所以我不会花很多时间去解释,基本上看了就明白了。

TextComponent是一个文本容器。Dim是定位。注意LeftEdge,label离开左边界18个像素。这是因为checkbox占了前面15像素的空间。

现在重要的来了!selection image。

注意我们给属性“name”复制为“selection”,as used in the StateImagery.Area部分还是定位和自适应。Dim用来确保整个item都被填满了。

ImageProperty定义了要使用的图像爱你个。我们已经在WidgetLook的前面某处定义了SelectionBrush。它现在只是用图填充那个区域(Area)。ColourProperty给image上色,我们也已经在WidgetLook的前面某处定义过SelectionColour了。VertFormat和HorzFormat是拉伸的(stretched),如果他没有被拉伸,它将只会画image的一个像素点,那就几乎不可见了。拉伸它是为了确保整个区域都被覆盖了。

完成!我们已经写好了我们的looknfeel entry!!

Pfew am I glad thats done.(基拉:我怀疑这是个拼写错误。作者文中多出拼写错误,有的我识别出来了,有的我真是搞不定,比如这句= =b)

给item写代码

到了实际考验我们的新item的时候了。我们需要再做一点工作来增加这个教程的完成度。首先,我们需要创建CheckListboxItem类。然后,我们要添加window工厂(factory)到系统中。最后,我们要做一个Falagard映射(mapping)。我们先从CheckListboxItem类开始吧。

CheckListItem.h

如你所见,这个类继承自ItemEntry。这是必需的,因为这样才能让我们的新item像个正常的item一样运作。需要特别注意的是这个CEGUI_DECLARE_WINDOW_FACTORY(CheckListboxItem). 它告诉CEGUI我们正在声明这个窗口。

CheckListItem.cpp

这里的CEGUI_DEFINE_WINDOW_FACTORY(CheckListboxItem) 非常重要。它告诉CEGUI我们在哪里放置和这个窗口相关的代码。如你所见,这个类非常空,你,当然,可以加任何你喜欢的东西到这个类里面来——这里写的只是类的基础框架。

现在,还有一件重要的事要做。在CEGUI中正确地注册这个窗口。

(译注:实践证明,addFalagardWindowMappings的第二个参数应该填你在CheckListboxItem.cpp里初始化的WidgetTypeName的值,在这个例子里就是“CEGUI/CheckListboxItem”,而不是它的基类“CEGUI/ItemEntry”。具体区别见本文顶部2012.10.15日更新)

addFalagardWindowMappings的参数分别是:名称(Name),类型(Type),LooknFeel,窗口渲染器(WindowRenderer)。只要把这段代码放在你的main文件的某处,或者放在其他你确定可以在使用我们的新item之前会被执行到的地方。还要注意,为了使用CEGUI_WINDOW_FACTORY(),你需要在CEGUI命名空间内部。

实例

main.cpp

如你所见,在这个main函数里,注册窗口的函数在实际创建窗口之前被调用了。不要在意SDL初始化的部分——那只是我的个人测试环境而已。

恭喜!你已经创建了一个CheckListboxItem了。这是一个非常好的练习,因为你也学会了如何写一个复合Widget。

如果你有任何疑问、评论、反馈……任何事的话,欢迎发邮件告诉我。我的邮件地址是 levia at openfrag dot com.


--User:Levia 21:10, 5 April 2007 (GMT+1)

====== 译者后记 =======

@DHorse WordPress太凶残了,我在你那个网站上上好色的XML代码它都吞,好象是见了尖括号就管不住嘴似的。我算怕了它了,全部贴图搞定!哇哈哈哈哈!!

Re: SSH 中文亂碼問題

文章由 fishman8 » 2011-09-09, 23:31

prereqirement: ipkg, optware-devel


#-----for ARM CPU
cd /volume1/@tmp
wget http://sourceforge.net/projects/dsgpl/f ... 8f628x.tgz
tar xvfz gcc421_glibc25_88f628x.tgz
cd arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/bin
cp locale /opt/bin
cp localedef /opt/bin
cd /volume1/@tmp
cp -R arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/share/i18n /usr/share
#-----keep another copy safe in case DSM is reinstalled later
cp -R arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/share/i18n /opt/share
mkdir /usr/lib/locale
localedef -c -f UTF-8 -i en_US en_US.utf8

然後用root 在 /etc/profile 檔案最後面加上
export LANG=en_US.UTF-8
就可以在 ssh 看到中文了。至少我 DS211j 是這樣成功的。

參考來源: http://pcloadletter.co.uk/2011/08/02/se ... ology-nas/

===================== 

以上转载自http://forum.synology.com/cht/viewtopic.php?f=6&t=3787

基拉补充:

ipkg安装是很早以前就完成了的,具体步骤我忘了= =

optware-devel的安装倒是可以说一下(其实就是照搬上面的参考来源= =)

ipkg update
ipkg install optware-devel

It will halt and complain that package wget-ssl clashes with wget. Continue with:

译:install optware-devel命令执行到一处会终止,原因是wget-ssl和wget冲突(真的!我也遇到了)。这时请按以下步骤解决:

cp /opt/bin/wget /opt/bin/wget-old
ipkg remove wget
cp /opt/bin/wget-old /opt/bin/wget
ipkg install libidn
ipkg install optware-devel

这次就能安好了。

(流水帐)

原因:

update失败是因为ipkg找不到它自己的wget(在/opt/bin/wget)。系统中有两个wget,另一个在/usr/syno/bin/wget。因为PATH变量中目录先后顺序的关系,系统会优先调用后者。

解决办法:

调整目录顺序

export PATH=/opt/bin:$PATH

(临时调整,重新登录失效)

然后ipkg update; ipkg install XXX 都可以正常运转了。

未解之谜:

为什么会变成这样?以前有段时间里都是没问题的呀?

参考文献:

http://forum.synology.com/enu/viewtopic.php?f=40&t=34693

我喜欢用ArrayList容器做参数,但总是为填充一个临时的ArrayList不够方便而苦恼。

比如说,以前,如果有一个ArrayList<String>做容器的函数 handleStrList(ArrayList<String> args) 的话,为了创建临时List喂给它,我会这样写:

handleStrListnew ArrayList<String>(){{
 add("string_1");
 add("string_2");
}})

上面的代码约等于:
class myTemp0001 extends ArrayList<String> {
   {
       add("string_1");
       add("string_2");
   }
}
handleStrListnew myTemp0001() )


写那么多个add很讨厌,也不优雅,但优雅的我不会- -

直到后来,我学到这招:

handleStrList(new ArrayList<String>( Arrays.asList("string_1","string_2") ) )

如果handleStrList函数不会增删改动它的参数的话,上面的 new ArrayList<String> 部分也可以省略:

handleStrList( Arrays.asList("string_1","string_2") )

优雅多了哈^_^

原理我懂,你一查你也知道,就不在这里卖弄了

这种小技巧对编程基本上没有什么帮助,不过偶尔想到了,觉得挺有趣的,就说一下吧。

果handleStrList函数不会增删改动它的参数的话,上面的

new ArrayList<String>(){{


handleStrList( new ArrayList<String>( Arrays.asList("string_1","string_2") ) )

  add("string_1")


;

  add("string_2");
}}


class myTemp0001 extends ArrayList<String> {
{

add

("string_1");

add("string_2");
}