当前位置: 首页 > 软件库 > 程序开发 > 网络工具包 >

Laminar

多人 fps 游戏 UDP 协议
授权协议 Apache 2.0
开发语言 Rust
所属分类 程序开发、 网络工具包
软件类型 开源软件
地区 不详
投 递 者 侯焱
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Laminar 是一种应用级传输协议,为快节奏的 fps 游戏提供基于 UDP 的可配置可靠性和排序保证,且提供轻量级的界面。

它的灵感来自 Gaffer on Games,功能类似 RakNet, Steam Socket, netcode.io。通过 Rust 写的低级 UDP 协议来支持多人游戏联网功能(尤其是 FPS 游戏),Laminar 一般用于 Amethyst 游戏引擎,不过没它也能用。

特性:

  • 碎片化
  •  不可靠的数据包
  •  不可靠的排序数据包
  •  可靠的无序数据包
  •  可靠有序的数据包
  •  可靠的排序数据包
  •  Rtt 估算
  •  协议版本监控
  •  基本连接管理
  •  Heartbeat
  •  基础的 DoS 缓冲
  •  高时序控制
  •  协议版本控制
  •  集成和单元测试良好
  •  可以被多个线程使用(Sender, Receiver)

协议

  • 握手协议
  • 高级连接管理
  • 密码密匙体系(Cryptography
  • 拥塞控制

用例:

UDP API - 发送数据

use laminar::{Socket, Packet};

// Creates the socket
let mut socket = Socket::bind("127.0.0.1:12345")?;
let packet_sender = socket.get_packet_sender();
// Starts the socket, which will start a poll mechanism to receive and send messages.
let _thread = thread::spawn(move || socket.start_polling());

// Bytes to sent
let bytes = vec![...];

// Creates packets with different reliabilities
let unreliable = Packet::unreliable(destination, bytes);
let reliable = Packet::reliable_unordered(destination, bytes);

// Specifies on which stream and how to order our packets, check out our book and documentation for more information
let unreliable = Packet::unreliable_sequenced(destination, bytes, Some(1));
let reliable_sequenced = Packet::reliable_sequenced(destination, bytes, Some(2));
let reliable_ordered = Packet::reliable_ordered(destination, bytes, Some(3));

// Sends the created packets
packet_sender.send(unreliable).unwrap();
packet_sender.send(reliable).unwrap();
packet_sender.send(unreliable_sequenced).unwrap();
packet_sender.send(reliable_sequenced).unwrap();
packet_sender.send(reliable_ordered).unwrap();

UDP API - 接收数据

use laminar::{SocketEvent, Socket};

// Creates the socket
let mut socket = Socket::bind("127.0.0.1:12346")?;
let event_receiver = socket.get_event_receiver();
// Starts the socket, which will start a poll mechanism to receive and send messages.
let _thread = thread::spawn(move || socket.start_polling());

// Waits until a socket event occurs
let result = event_receiver.recv();

match result {
    Ok(socket_event) => {
        match socket_event {
            SocketEvent::Packet(packet) => {
                let endpoint: SocketAddr = packet.addr();
                let received_data: &[u8] = packet.payload();
            }
            SocketEvent::Connect(connect_event) => { /* a client connected */ }
            SocketEvent::Timeout(timeout_event) => { /* a client timed out */ }
            SocketEvent::Disconnect(disconnect_event) => { /* a client disconnected */ }
        }
    }
    Err(e) => {
        println!("Something went wrong when receiving, error: {:?}", e);
    }
}
  • 传送门 很容易想到,离线按路径长度从大到小排个序,用树链剖分加颗支持区间cover的线段树就好了 代码: #include<cstdio> #include<iostream> #include<algorithm> using namespace std; void read(int &x){ char ch; bool ok; for(ok=0,ch=getchar(); !i

  • Problem L. Laminar Family Input file: standard input Output file: standard output Time limit: 3 seconds Memory limit: 512 mebibytes While studying combinatorial optimization, Lucas came across the not

  • http://codeforces.com/gym/101630/attachments 按链长度降序排序 一条条的向树上着色 每次着色之前先看当前链上是不是同一种颜色 线段树维护一下 是的话就更新 不是一种颜色 那就说明有冲突   #include <bits/stdc++.h> using namespace std; typedef pair<int,int> pii; const int

  • 题目大意:有一棵 n n n 个结点的树,有 f f f 条简单路径,定义 f [ i ] f[i] f[i] 为 第 i 条路径的点集,判断这 f f f 条路径任意两条是否满足: 1. f [ i ] f[i] f[i] 和 f [ j ] f[j] f[j] 没有公共部分 2. f [ i ] f[i] f[i] 是 f [ j ] f[j] f[j] 的子集 3. f [ j ] f[j]

  • 题目链接 http://codeforces.com/gym/101630/attachments/download/6401/20172018-acmicpc-northeastern-european-regional-contest-neerc-17-en.pdf 题意 给出一棵树和一组操作,操作的格式是给出 u、v u 、 v 两个节点,并将该节点所确定的路径上的节点全部加入到一个新的集合

  • 题意:      给你一颗树,每次选取一个路径,把路径上的所有点加入到一个集合里面,问最后的集合是否两两之间满足 A∈B A ∈ B 或者 B∈A B ∈ A 或者 A∪B=∅ A ∪ B = ∅ 思路:     我们发现,如果最后是符合条件的,那么必定是一个集合被另一个集合套的这样的形式,也就是说一个集合是完全套在另一个集合上面的。这个很明显可以利用线段树维护,那么我们开始把所有集合按集合大小从

  • 题目链接:https://cn.vjudge.net/problem/Gym-101630L 题目大意:   对于一个集合的集合,若其中任意两个集合 \(A\) 和 \(B\) 都满足下述三个条件之一:\(A \subset B\) 或 \(B \subset A\) 或 \(A \cap B = \varnothing\),则称这个集合 \(laminar\).   给定一棵有 \(N\) 个结

 相关资料
  • 每2个玩家,服务器将创建1个房间(我的游戏是PvP,一对一) 每个房间处理游戏逻辑 我将使用作为我的游戏循环 服务器FPS=5 每个房间都可以处理玩家的移动和一些物理操作 关于实际问题: 基于下面的点数,我应该使用什么样的游戏循环?下面每种类型的游戏循环的利弊是什么。 null

  • 我正在做一个多人游戏。每个客户端都有一个在共享环境中移动的字符。 我使用socket.io创建rooms,使用peer.js创建客户端之间的点对点连接。 我正在尝试做的是使每个客户端能够更新他的地图中其他玩家的角色的位置。 为此,每个客户端应该拥有其他玩家的键盘光标(箭头键)的状态,以便他能够用行走动画移动他们对应的角色。 p2p:我正在考虑在客户端之间创建双工流,这样每个客户端将拥有其他玩家的键

  • 我已经成功创建了一个系统,允许游戏对象根据时间的变化(而不是帧数的变化)移动。为了练习起见,我现在正在尝试设置FPS限制。 我遇到的问题是,游戏循环的数量是我预期的两倍。例如,如果我尝试将帧数限制为1fps,则在一秒钟内会有2帧通过-一个非常长的帧(~1秒)和一个非常短的帧(~ 15毫秒)。这可以通过输出每个游戏循环之间的时间差(毫秒)来显示-示例输出可能是993、17993、16。。。 我尝试过

  • Iphone Gamekit对于创建多人游戏非常有用。 但我有个问题。互联网上有很多资源和教程,可以为通过血牙或WiFi加入的玩家创建多人游戏。但玩家应该通过同一网络连接。但是有没有一种方法可以连接世界上任何地方的用户。举个例子,假设在一个纸牌游戏中,我是一个玩家,游戏会搜索全世界的用户,随机连接3个玩家与我一起玩游戏。有没有办法用GameKit做到这一点。如果这是可能的,任何人可以请指示我一些关

  • 我正在开发一个基于Java(客户机和服务器)的多人策略游戏。我没有太多的经验在网络游戏,但我做过一些小事情,像一个多功能聊天和2个玩家的抽签tac脚趾与插座。我不是在找人为我编写代码,只是给我一些指导。 游戏经历了多个阶段:首先,用户连接并登录。在他被赋予主持/加入游戏的选择权之后。在他加入一个游戏或者某人加入他的游戏之后,客户端就会继续进入游戏阶段。游戏是1v1的,只需要每隔5秒来回发送数据(如

  • 我正在尝试构建一个使用套接字和udp协议的python在线游戏。我创建了一个多处理和多线程服务器:https://pastebin.com/zucxwpc9。 我会解释里面的代码是做什么的。所以首先,它等待两个请求,并将它们放入lobby列表中。如果发出了两个请求,服务器将向客户端发送一个新端口,并创建一个具有两个线程的新进程。两个线程都在使用新端口,一个接收数据,另一个发送数据。我正在使用队列,

  • 我正在使用JavaScript中的套接字io创建一个多人游戏。除了客户端插值之外,游戏目前的工作非常完美。现在,当我从服务器获得一个数据包时,我只需将客户端的位置设置为服务器发送的位置。以下是我尝试做的: 所以我设定了球员的目标位置。然后在玩家更新方法中我简单地做了这样的操作: 这基本上使玩家以固定的速度向目标的方向移动。问题是玩家在下一个信息从服务器到达之前或之后到达目标。 编辑:我刚刚读了Ga

  • 不知道为啥在****上投了一万个数据分析岗没回应,结果多益的hr直接找上来问我对游戏玩的多不多,对游戏策划感不感兴趣,莫名其妙的就投了简历,填完了测评(看别人都说有些都乱填,就我兢兢业业填了快一千多个字?),明天笔试不知道考啥 多益很缺策划?鼠鼠就一破打游戏的能面游戏策划吗? 8.5一面(面试官的麦经常会听不清,反问了好几次,然后回答问题的时候眼睛不由自主往左下瞄,我也不知道为啥,下次屏幕中间贴个