关于l2j_server研究(一)

L2j_server研究 Powered by chenlei

本文只是在自己看源码写的一点点,很乱。有什么可以直接线上讨论群:275459491  陈磊


1.       事件,事件监听器机制;

L2j_server世界中的所有的事件,都对应有一个事件监听器:InterfaceEnvet—事件接口(l2Event),所有的事件都会去具体实现InterfaceEnvet,从而构成游戏中的事件源。当然这里对于物品的事件就是(创建,销毁,丢弃,拾取,交易,装备)等事件;监听器:L2j_server中,有一个L2JListener的抽象类(主要有些函数需要子类去实现硬编码),有一个变量就是L2PcInstance---游戏的玩家角色,另外就是两个函数:register(),unregister(),注册监听事件,取消监听事件,这里针对物品的话就是,注册的NewItemListener(抽象类—定义有不同的行为(所有的事件监听器都是抽象类))这个监听器,每个监听器上有一个事件监听list,物品的话,就是newItemListeners,不同的监听器,有定义不同的行为,具体的子类去实现监听器的行为;这里public boolean onCreate(ItemCreateEvent event)—注意了这里是返回的boolean值;物品的创建,这样就和具体的事件关联了。另外还有一个重要的类L2Script,成员变量_listeners。他包含了所有事件的监听列表,在L2Script抽象类中,注册,移除监听器;注册事件,取消事件通知是对应的,事件的监听针对角色的行为。

2.       物品系统:

物品系统分三类:L2Item,L2ItemInstance,L2ItemTable. 这三个类构成了L2j的服务端物品架构;L2Item抽象类,规定物品的基础属性,

L2ItemInstance 是指将一个物体呈现在客户端上时所包含的属性以及方法。比如是否是有时间上的限制,是什么样的东西?防具还是武器,魔法效果,呈现地点;注意,构造函数中L2ItemInstance(int objectId, int itemId),物品的世界唯一ID,物品itemId,此外,是呈现在游戏世界中的物品l2word,因此继承l2object,并且指明类型setInstanceType(InstanceType.L2ItemInstance);Ientable类主要实现物品的加载,

类型划分的Map

  

*/

    public static final Map<String, Integer> _materials = new FastMap<>();//材料

    public static final Map<String, Integer> _crystalTypes = new FastMap<>(); // 水晶

    public static final Map<String, Integer> _slots = new FastMap<>();

 

 

    public static final Map<String, L2WeaponType> _weaponTypes = new FastMap<>();

    public static final Map<String, L2ArmorType> _armorTypes = new FastMap<>();

   

 

 

    private L2Item[] _allTemplates; //配置--存储物品的数组

 

    private Map<Integer, L2EtcItem> _etcItems;

    private Map<Integer, L2Armor> _armors;

    private Map<Integer, L2Weapon> _weapons;

这里一大堆的map,所有的物品信息都是在DocumentEngine.getInstance().loadItems()加载,配置全是xml,在datapack中,分类加载,最后绑定物品到一个数组中_allTemplates,根据下标快速获取Item,public L2ItemInstance createItem(String process, int itemId, long count, L2PcInstance actor, Object reference)—产生物品,根据物品的ItemID,和IDfactory,组装一个物品;---注意这里是actor触发即是player;destroyItem(String args[]….)销毁物品,有一个关键字synchronized(Item),这里就不说为什了。整个物品基础系统就有了。

具体的还有很多,譬如容器(背包吧)Inventory…..后面在说吧

3.L2j_server的业务处理

L2j_server的业务处理的对象引用,基本上都是使用的单例模式,

public class a{

private a(){}

public static a getInstance(){

return singleton.obj;

}

private static final class singleton{

private static final a obj=new a();

}

}

这样在处理业务时,就节省了系统创建对象的开销,并且在多线程的环境下,是线程安全的。

欢迎讨论


 

 

转载于:https://my.oschina.net/chenleijava/blog/85144

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
v4l2 VIDIOC_EXPBUF是用于向驱动程序请求分配视频缓冲区的ioctl命令。它用于在视频捕获设备上分配一个或多个视频缓冲区,以便在视频流中存储捕获的帧。 以下是使用v4l2 VIDIOC_EXPBUF的示例代码[^1]: ```c struct v4l2_requestbuffers reqbuf; memset(&reqbuf, 0, sizeof(reqbuf)); reqbuf.count = 1; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) { perror("VIDIOC_REQBUFS"); exit(EXIT_FAILURE); } struct v4l2_buffer buffer; memset(&buffer, 0, sizeof(buffer)); buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; buffer.index = 0; if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) == -1) { perror("VIDIOC_QUERYBUF"); exit(EXIT_FAILURE); } buffer.length = buffer.bytesused; buffer.start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buffer.m.offset); if (buffer.start == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } if (ioctl(fd, VIDIOC_QBUF, &buffer) == -1) { perror("VIDIOC_QBUF"); exit(EXIT_FAILURE); } enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) { perror("VIDIOC_STREAMON"); exit(EXIT_FAILURE); } ``` 在上述代码中,我们首先使用VIDIOC_REQBUFS命令请求分配一个视频缓冲区。然后,我们使用VIDIOC_QUERYBUF命令查询缓冲区的信息,并使用mmap函数将缓冲区映射到用户空间。接下来,我们使用VIDIOC_QBUF命令将缓冲区放入队列中。最后,我们使用VIDIOC_STREAMON命令启动视频流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值