Unix Note--errno define

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */
#define EOWNERDEAD 130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */
#define ERFKILL 132 /* Operation not possible due to RF-kill */
#define EHWPOISON 133 /* Memory page has hardware error */

游戏评测8——Minecraft(简评)

好久没有写东西了。这里吧欠了很久的MC补上吧。
感觉对于Minecraft这款游戏并没比较完整的体验,但是个人来讲它对我的吸引力并不大,所以暂时也没有什么玩下去的动力了。不过这并不说明MC不是一款好的游戏,恰恰相反的是,这款游戏有着众多的粉丝支持,同时微软以25亿美元的高价将其购买也说明了其巨大的影响力以及市场价值,Minecraft是一款十分优秀的沙盒游戏,也可能是目前市面上最好的沙盒游戏。下面是我对这款游戏的简评(可能会夹杂比较多的主观因素)。

Minecraft由Notch(Markus Persson)和Jeb(Jens Bergensten)开发,于2011年11月18日发售,之后相继提供了各平台的支持包括PC、Android(Pocket Edition)、iOS(Pocket Edition)、Windows Phone(Pocket Edition)、PlayStation 4、PlayStation 3、PlayStation Vita、XBOX One、XBOX 360、树莓派。这也使得更多的玩家可以体验这款游戏。

游戏包括创造、生存和极限生存三种模式。创造模式下玩家可以获得任意数量的资源,同时可以一次秒掉一个方块,同时不会受到伤害,这种模式给建筑党们提供了一个非常好的平台来创造自己所想创造的(丧心病狂的)建筑,下面会详细介绍。生存模式的游戏方式与之前所说过得Terraria的想法类似,玩家通过从世界中获取资源进行建造房屋,制造工具,与NPC互动等活动来进行自己的发展以及对地图的发展完成生存,挑战boss等。极限生存与生存模式类似,只是当玩家死亡后游戏便会结束(生存模式玩家会在出生点复活),大概就是其他游戏中的hard难度吧。

这里就从生存模式开始介绍(由于手残的比较厉害所以没有作死去玩极限生存模式)。创建并进入地图后玩家没有任何道具,正常流程是找到一棵树,对着树干左键,之后会获得原木,通过初始的制造功能完成工作台的制作。工作台制作好后继续伐木在工作台制造出木斧和木镐,继续获取资源生级手上的工具,需要注意的是天黑前给自己建个房子。游戏在夜间会刷怪僵尸小白什么的,这些怪物在白天会燃烧然后挂掉,所以白天不在地下的话还是比较安全的,但是晚上没有地方住的话大概就会挂掉吧(反正我挂掉了OwO)。之后的流程大概就是升级工具,挖矿,探索巩固自己的家,制造武器打BOSS获取材料制造新的东西。

获取资源大概是这个游戏的重点吧,通过对镐和斧子的升级可以加速玩家获取树木和矿物的速度,这样的激励给玩家带来了一种很好的体验,通过自己的努力提高了获取资源的速度从而使得游戏变得简单,玩家可以感受到自己在游戏中的进度,比如说前期玩家用木镐挖矿的效率就比后期的钻石镐慢很多。弓和剑还有身上穿的装甲也是同样的感觉,杀怪更方便,更快的获取经验(经验系统之后会说)。

当初期的进度差不多时,玩家便可构建出地狱传送门进行地狱的探索,来获取新的东西。之后还有末影地啥的我没有去过这里就不说了。探索方面游戏中会随机生成村庄、地牢、矿井沙漠遗迹等特殊环境,玩家可以在其中进行与NPC的交易以及获取一些比较稀有的资源,从探索的角度来说,这种激励使得玩家会去更多的探索地图,同时也提高了游戏性。

生存游戏中饥饿度是比较常见的设定,当然


未完待续= =

C++API设计Note

整理自《C++ API设计》一书中的提示,不定期更新


1.特征

  • 避免将函数声明为可以重写的(虚)函数,除非你有合理而迫切的需求
  • 基于最小化的核心API,以独立的模块或苦地行使构建便捷API
  • 使用枚举类型代替布尔类型,可以提高代码的可读性
  • 避免编写拥有多个相同类型参数的函数
  • 使用一致的函数命名和参数顺序

Unix编程入门2--线程同步

意义

当一个线程可以修改的变量,其他的线程也可以读取或修改的时候,我们就需要进行线程同步,以确保线程在访问资源是不会获取无效的值。

几种线程同步涉及到的几种技术

互斥量(mutex)

互斥量从本质上讲是一把锁,在访问共享资源前对互斥量进行设置(加锁),访问完成后释放(解锁)互斥量。这样可以确保同一时间只有一个线程访问资源,防止数据不一致的出现。
互斥量使用pthread_mutex_t数据类型表示,使用前需进行初始化,可将其设置为常量PTHREAD_MUTEX_INITIALIZER,也可通过调用pthread_mutex_init函数进行初始化。如果动态分配互斥量,在释放内存时需要调用pthread_mutex_destroy。

1
2
3
4
5
6
7
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *rerestrict attr);
/* attr一般设为NULL表示以默认属性初始化互斥量 */
int pthread_mutex_init(pthread_mutex_t *mutex);
/* 函数返回:成功返回0,失败返回错误码 */

加锁和解锁:

1
2
3
4
5
6
7
8
9
10
11
12
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
/* 对互斥量加锁 */
int pthread_mutex_trylock(pthread_mutex_t *mutex);
/* 如果互斥量未加锁对互斥量加锁,不会组阻塞且返回0; 如已经加锁该操作就会失败,无法所互斥量并返回EBUSY */
int pthread_mutex_unlock(pthread_mutex_t *mutex);
/* 解锁 */
/* 函数返回:成功返回0,失败返回错误编号 */

当互斥量已经上锁时,调用线程将阻塞直到互斥量被解锁。

例程
PS:

1
2
3
4
5
#include <pthread.h>
#include <time.h>
int pthread_mutex_timedlock(pthread_mutex_t * restrict mutex,
const struct timespec *restrict tsptr);
/* 成功返回0,失败返回错误编号 */

当该函数调用时,互斥量原语允许绑定线程阻塞时间(tsptr),未超时时,其表现与pthread_mutex_lock一致对互斥量加锁,当超时后则不会对互斥量加锁,而是返回ETIMEDOUT。
该函数的使用主要是为了防止在死锁时所造成的永久阻塞。

###

游戏评测7——To The Moon

这里说明一下,上一篇说要做minecraft然后……被各种大触吓尿了,同时然后自己的生存测试也不是很顺利。最近也是一周七天天天有课所以也没什么时间去玩啊,所以花了点时间完成了之前进行了一半的To the moon就有了现在的这一篇评测。不过呢,这篇说是评测倒不如说是一篇推荐,希望各位不要因为我这拙劣描述而错过一款佳作,嘿嘿~


梦想何时开始都不算晚,只是那追梦人是否还沉沦在现实的梦境中
image
RPGMAKER引擎制作的角色扮演游戏。这虽然是个像素画微型游戏,流程只有几个小时并且没有真正的战斗;但是本作凭借精美细腻的演出效果,和感人的故事发展获得了许多好评。尤其是在2011 年GameSpot的年度最佳游戏中,胜过凯瑟琳,传送门2等众多大作而获得了最佳剧本奖。
游戏于2011年的光棍节发售,平台为WINPC,由于像素化的原因几乎没有体验的门槛,所以在哪天抽出几个小时体验这样一款制作精良的游戏绝对物超所值。

这款游戏为我们带来了一段十分感人故事,以一个旁观者的角度,通过记忆的信标,将整段记忆串联、挖掘、改写最后如我们所熟知的结束。人的一生究竟该如何度过?其实,快乐就好。

作为一款主打故事线的游戏,再多说就是剧透了,有时间的朋友可以体验一下,你不会失望的。

最后推荐下这段视频,有看点:游戏内外的那些梦想http://www.bilibili.com/video/av696528/
To the moon这款游戏我也是从这里了解到的。


以上(下期预告依旧MC……祝我成功Orz)

CE3备忘录4--FireMode

关于备忘录:
这里主要是自己记录一些CE3(Cryengine3)的常用方法,包括代码编写以及API功能,如果有什么问题感谢指出,这是我的邮箱albstein2@gmail.com


这里简单介绍FireMode的写法。

首先说明下CE3武器系统的调用结构:
在CE3中当触发射击事件的时候一般来说是这样的流程,首先调用到当前武器,在武器代码中通过m_fm成员调用FireMode的方法之后,通过FireMode完成射击动作,发射出的弹头造成伤害。

以上的这些关联均在xml文件中定义,可以在允许的范围内自由调用。

接下来就说FireMode了,因为之前一直没有怎么用过所以没怎么研究。最开始使用的时候直接继承下来,然后重载要用的函数,但是实践后发现会造成一个断言失败,之后调试的结论是FireMode的每个成员函数中都有自己的内存管理方法,由于调用了this指针所以所有的子类都需要定义这一方法,以保证内存的合理使用,当然在其中还使用一个宏定义来辅助完整这一任务。不过这里确实是给我造成了一些困扰,毕竟宏很少用啊。其中代码块分别使用了两组宏定义实现了这一方法的声明与定义

好的~
接下来话不多说,咱们来看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef __MYFM_H__
#define __MYFM_H__
#include "Single.h"
//这里从Single中继承下来
class CLock : public CSingle
{
private:
typedef CSingle BaseClass;
public:
CRY_DECLARE_GTI(CMyFM);//迷之宏定义的声明部分
//从注释来说大概是获取静态和运行时的信息
//由于免费版源代码并没有完全开放,这里个人推测获取的信息在之后的GetMemoryUsage方法中需要使用
CMyFM();
virtual ~CMyFM(){};//注意这里的虚析构函数
virtual void GetMemoryUsage(ICrySizer * s) const;
//前面说的内存管理
//你想要重载的函数
private:
//所需的成员
};
#endif

cpp的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "StdAfx.h"
#include "Lock.h"
#include "Projectile.h"
CRY_IMPLEMENT_GTI(CMyFM, CSingle);//迷之宏定义的实现部分
void CMyFM::GetMemoryUsage(ICrySizer * s) const
{
s->AddObject(this, sizeof(*this));
BaseClass::GetInternalMemoryUsage(s); // collect memory of parent class
}
//内存的管理
//你所需要的的方法的实现

使用的时候需要改写使用这一FireMode的武器xml中的FireMode标签,改成在GameFactory.cpp中注册的名称即可使用,关于注册方法与Weapon的注册方法相同。
这样整个武器系统的编写就完成了,当然关于一些奇怪武器的编写还要了解其他的API这里就不再赘述。

以上

Ubuntu下Sublime Text 2的安装Fix

貌似在很久以前写过一篇ST安装的文档,然后在最后的启动器设置的时候失败了,之后我在使用的时候解决了这个问题,在这里简单说一下。


当然,之前的启动器如果可以用的话可能涉及到系统神马的问题?这里不是很懂,下面是我最后成功时的配置:

与之前一样,在/usr/share/applications目录下新建文档,命名为sublime.desktop

之后编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Desktop Entry]
Version=1.0
Type=Application
Name=Sublime Text
GenericName=Text Editor
Comment=Sophisticated text editor for code, markup and prose
Exec=sublime %F
Icon=/usr/lib/Sublime Text 2/Icon/sublime.png
Terminal=false
MimeType=text/plain;
Categories=TextEditor;Development;
StartupNotify=true
Actions=Window;Document;
[Desktop Action Window]
Name=New Window
Exec=sublime -n
OnlyShowIn=Unity;
[Desktop Action Document]
Name=New File
Exec=sublime --command new_file
OnlyShowIn=Unity;

具体的细节我就不作说明了,需要注意的几点是

1
2
3
Name:代表该应用的名字
Icon:代表图标所在路径(当然我们可以根据这点来改变图标,搜索相关内容既可获取一些更加好看图标以更换)
Exec:内容为应用的路径以及启动参数(这里由于我已经将sublime的路径加入环境变量,所以可以直接使用)

关于更加具体的使用方法网络上有可获取的资源供大家参考,但是当时忘记保存网址了所以……这里没办法给出链接了
关于更换图标的问题:由于网络上获取的资源可能有格式的问题,这里提供给大家一个图片格式在线转换的网站

当然关于sublime的设置还有很多可以说的地方,这里我就不一一列举了,推荐给大家一个不错的链接里面的东西较为详细。包括主题和快捷操作什么的。

这是我配置完成的效果:
image

一激动手滑敲错了点东西也没管就截图了,啊,大家就当没看到= =

最后附上Sublime Text的一些快捷操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Ctrl+Shift+P:打开命令面板
Ctrl+P:搜索项目中的文件
Ctrl+G:跳转到第几行
Ctrl+W:关闭当前打开文件
Ctrl+Shift+W:关闭所有打开文件
Ctrl+Shift+V:粘贴并格式化
Ctrl+D:选择单词,重复可增加选择下一个相同的单词
Ctrl+L:选择行,重复可依次增加选择下一行
Ctrl+Shift+L:选择多行
Ctrl+Shift+Enter:在当前行前插入新行
Ctrl+X:删除当前行
Ctrl+M:跳转到对应括号
Ctrl+U:软撤销,撤销光标位置
Ctrl+J:选择标签内容
Ctrl+F:查找内容
Ctrl+Shift+F:查找并替换
Ctrl+H:替换
Ctrl+R:前往 method
Ctrl+N:新建窗口
Ctrl+K+B:开关侧栏
Ctrl+Shift+M:选中当前括号内容,重复可选着括号本身
Ctrl+F2:设置/删除标记
Ctrl+/:注释当前行
Ctrl+Shift+/:当前位置插入注释
Ctrl+Alt+/:块注释,并Focus到首行,写注释说明用的
Ctrl+Shift+A:选择当前标签前后,修改标签用的
F11:全屏
Shift+F11:全屏免打扰模式,只编辑当前文件
Alt+F3:选择所有相同的词
Alt+.:闭合标签
Alt+Shift+数字:分屏显示
Alt+数字:切换打开第N个文件
Shift+右键拖动:光标多不,用来更改或插入列内容
鼠标的前进后退键可切换Tab文件
按Ctrl,依次点击或选取,可需要编辑的多个位置
按Ctrl+Shift+上下键,可替换行

就这样

Unix编程入门1--ls简单实现及分析

这个入门系列来自《UNIX高级编程》之后的东西大都是来自这本书,在这里自己记录下。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "apue.h"
#include <dirent.h>
int main(int argc, char* argv[])
{
DIR *dp;
struct dirent *dirp;
if (argc != 2)
err_quit("usage: ls directioy_name");
if((dp = opendir(argv[1])) == NULL)
err_sys("can't open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);
closedir(dp);
exit(0);
}

上面这段就是ls指令的一个简单的实现,当然如果你直接复制这段代码的话它是无法编译通过的。书中将一些常用的头文件以及异常的处理都放在了一起,也就是apue.h中所以在这段程序编译之前我们需要进行以下工作。

首先进入这本书的官网,打开最新版的链接下载Source Code中的源码,下载完成后,解压文件在找到路径下的./apue.3e/include/apue.h和./apue.3e/lib/error.c将其移动到/usr/include下,(sudo cp 啥的= =都知道吧)之后打开apue.h将error.c加入apue.h中,具体位置实在结尾处的#endif之前
这样:

apue.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* Our own header, to be included before all standard system headers.*/
#ifndef _APUE_H
#define _APUE_H
#define _POSIX_C_SOURCE 200809L
#if defined(SOLARIS) /* Solaris 10 */
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 700
#endif
#include <sys/types.h> /* some systems still require this */
#include <sys/stat.h>
#include <sys/termios.h> /* for winsize */
#if defined(MACOS) || !defined(TIOCGWINSZ)
#include <sys/ioctl.h>
#endif
#include <stdio.h> /* for convenience */
#include <stdlib.h> /* for convenience */
#include <stddef.h> /* for offsetof */
#include <string.h> /* for convenience */
#include <unistd.h> /* for convenience */
#include <signal.h> /* for SIG_ERR */
#define MAXLINE 4096 /* max line length */
/* Default file access permissions for new files. */
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
/* Default permissions for new directories. */
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
typedef void Sigfunc(int); /* for signal handlers */
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/* Prototypes for our own functions. */
char *path_alloc(size_t *); /* {Prog pathalloc} */
long open_max(void); /* {Prog openmax} */
int set_cloexec(int); /* {Prog setfd} */
void clr_fl(int, int);
void set_fl(int, int); /* {Prog setfl} */
void pr_exit(int); /* {Prog prexit} */
void pr_mask(const char *); /* {Prog prmask} */
Sigfunc *signal_intr(int, Sigfunc *); /* {Prog signal_intr_function} */
void daemonize(const char *); /* {Prog daemoninit} */
void sleep_us(unsigned int); /* {Ex sleepus} */
ssize_t readn(int, void *, size_t); /* {Prog readn_writen} */
ssize_t writen(int, const void *, size_t); /* {Prog readn_writen} */
int fd_pipe(int *); /* {Prog sock_fdpipe} */
int recv_fd(int, ssize_t (*func)(int,
const void *, size_t)); /* {Prog recvfd_sockets} */
int send_fd(int, int); /* {Prog sendfd_sockets} */
int send_err(int, int,
const char *); /* {Prog senderr} */
int serv_listen(const char *); /* {Prog servlisten_sockets} */
int serv_accept(int, uid_t *); /* {Prog servaccept_sockets} */
int cli_conn(const char *); /* {Prog cliconn_sockets} */
int buf_args(char *, int (*func)(int,
char **)); /* {Prog bufargs} */
int tty_cbreak(int); /* {Prog raw} */
int tty_raw(int); /* {Prog raw} */
int tty_reset(int); /* {Prog raw} */
void tty_atexit(void); /* {Prog raw} */
struct termios *tty_termios(void); /* {Prog raw} */
int ptym_open(char *, int); /* {Prog ptyopen} */
int ptys_open(char *); /* {Prog ptyopen} */
#ifdef TIOCGWINSZ
pid_t pty_fork(int *, char *, int, const struct termios *,
const struct winsize *); /* {Prog ptyfork} */
#endif
int lock_reg(int, int, int, off_t, int, off_t); /* {Prog lockreg} */
#define read_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define readw_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define write_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define writew_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define un_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))
pid_t lock_test(int, int, off_t, int, off_t); /* {Prog locktest} */
#define is_read_lockable(fd, offset, whence, len) \
(lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) \
(lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)
void err_msg(const char *, ...); /* {App misc_source} */
void err_dump(const char *, ...) __attribute__((noreturn));
void err_quit(const char *, ...) __attribute__((noreturn));
void err_cont(int, const char *, ...);
void err_exit(int, const char *, ...) __attribute__((noreturn));
void err_ret(const char *, ...);
void err_sys(const char *, ...) __attribute__((noreturn));
void log_msg(const char *, ...); /* {App misc_source} */
void log_open(const char *, int, int);
void log_quit(const char *, ...) __attribute__((noreturn));
void log_ret(const char *, ...);
void log_sys(const char *, ...) __attribute__((noreturn));
void log_exit(int, const char *, ...) __attribute__((noreturn));
void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);
#inlcude "error.c" /*加到这里*/
#endif /* _APUE_H */

以上的工作完成后我们就可以编译运行这个程序了

我们将可执行文件命名为myls,当权限允许时,执行myls后会得到作为参数输入路径的所用文件的文件名

  • ./myls /

这样程序就会返回root下的所有文件名

下面介绍下这段程序中的API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "apue.h"
#include <dirent.h>
int main(int argc, char* argv[])
{
DIR *dp;
struct dirent *dirp;
if (argc != 2)
err_quit("usage: ls directioy_name");
if((dp = opendir(argv[1])) == NULL)
err_sys("can't open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);
closedir(dp);
exit(0);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DIR *opendir(const char *pathname);
//成功时返回DIR指针,出错返回NULL
//获取DIR指针
struct dirent *readdir(DIR *dp);
//成功返回指针,若在目录尾出错返回NULL
//返回值为目录中的第一个目录项(个人感觉类似文件读取时的文件指针FILE*)
//例子中当执行到文件尾端是返回NULL这样可以便利本目录下的所有目录
int closedir(DIR *dp);
//成功返回0,出错返回-1
//销毁指针
//DIR是一种目录处理需要的结构,保存目录相关信息,由打开文件的描述符转化而来
//struct dir中记录的为文件信息,显示为以下形式
struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长256字符 */
}

以上


如果什么地方有错误的话请联系我~
这是我的邮箱:albstein2@gmail.com

CE3备忘录3--暗杀(Stealthkill)bug的简单处理

关于备忘录:
这里主要是自己记录一些CE3(Cryengine3)的常用方法,包括代码编写以及API功能,如果有什么问题感谢指出,这是我的邮箱albstein2@gmail.com


在使用CE3时遇到点问题,当从背后靠近敌人时,我们使用近战攻击时敌人会直接死亡,但是我们在之后却无法移动,

断点调试后,发现在这种情况下实际是触发了引擎中自带的暗杀系统,而在这一部分中我们并没有提供相应的暗杀动作在其中,这就会触发这个bug(当然具体的问题我还没有定位到)

下面为有同样问题的开发者们提供一个可行的解决办法,就是直接把调用暗杀的部分去掉(既然没有动画,那我们就不用它了)

下面是我通过调试找到的代码段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bool CPlayerInput::OnActionSpecial(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CallTopCancelHandler())
{
return false;
}
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if (activationMode == eAAM_OnPress)
{
if (interactionInfo.interactionType == eInteraction_Stealthkill)
{
m_pPlayer->AttemptStealthKill(interactionInfo.interactiveEntityId);//这里调用的暗杀
}
else if (interactionInfo.interactionType == eInteraction_LargeObject)
{
if(!m_pPlayer->GetLargeObjectInteraction().IsBusy())
{
m_pPlayer->EnterLargeObjectInteraction(interactionInfo.interactiveEntityId); //always use power kick in MP
}
}
}
return false;//如方法名,这里触发的是特殊动作,前面两段代码都没有执行的话,就会进入正常的近战流程
}

代码可以通过搜索的方法简单的定位到,之后我们只需将调用暗杀的哪行注释掉就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
bool CPlayerInput::OnActionSpecial(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CallTopCancelHandler())
{
return false;
}
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if (activationMode == eAAM_OnPress)
{
if (interactionInfo.interactionType == eInteraction_Stealthkill)
{
//我们把它注释掉
//m_pPlayer->AttemptStealthKill(interactionInfo.interactiveEntityId);
}
else if (interactionInfo.interactionType == eInteraction_LargeObject)
{
if(!m_pPlayer->GetLargeObjectInteraction().IsBusy())
{
m_pPlayer->EnterLargeObjectInteraction(interactionInfo.interactiveEntityId); //always use power kick in MP
}
}
}
return false;
}

好的,这样当我们从敌人背后悄悄靠近的时候就可以用近战愉快的揍他了