zpl-c / enet Goto Github PK
View Code? Open in Web Editor NEW⚡️ ENet reliable UDP networking library
Home Page: https://blog.zpl.pw
License: MIT License
⚡️ ENet reliable UDP networking library
Home Page: https://blog.zpl.pw
License: MIT License
It would be great if you could provide the shared libraries (DLL for Windows at least) in the release section for people.
I run the server then have two clients connect to it. Both clients and server are sending "hello world", which works fine. Then I harshly disconnect one client by hitting ctl-c
. What ends up happening is that the server eventually stops receiving incoming packets at all.
I added printfs to the header to see what's happening, and it looks like it gets stuck trying to send to the disconnected peer and ignores everything else.
Frame output:
--- host_service ---
Send outgoing 1 // First call to enet_protocol_send_outgoing_commands
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
peer 0
No commands...continuing
peer 1
Sending packet to peer 1
Receive incoming // Call to enet_protocol_receive_incoming_commands
send outgoing 2 // second call to enet_protocol_send_outgoing_commands
peer 0
No commands...continuing
peer 1
No commands...continuing
dispatch incoming // Top of enet_host_service
Returning because host service time is lequal to timeout
--- host_service --- // next frame
Normal frames with both peers connected look like a loop of this:
--- host_service ---
Send outgoing 1
peer 0
Sending packet to peer 0
peer 1
Sending packet to peer 1
Receive incoming
Received incoming packet of length 21
Peer 1: adding to dispatch list
Received incoming packet of length 10
Received incoming packet of length 21
Peer 0: adding to dispatch list
Received incoming packet of length 10
send outgoing 2
peer 0
Sending packet to peer 0
peer 1
Sending packet to peer 1
dispatch incoming
Peer 1 received
Message recieved! HELLO WORLD
--- host_service ---
Peer 0 received
Message recieved! HELLO WORLD
--- host_service ---
Send outgoing 1
peer 0
No commands...continuing
peer 1
No commands...continuing
Receive incoming
send outgoing 2
peer 0
No commands...continuing
peer 1
No commands...continuing
dispatch incoming
Returning because host service time is lequal to timeout
--- host_service ---
Repro example:
#include <cstdio>
#define ENET_IMPLEMENTATION
#include "enet.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
void run_server();
void run_client();
int main (int argc, char** argv) {
if (enet_initialize() < 0) {
printf("failed to initialize enet\n");
};
bool server;
if (argc == 2 && !strcmp(argv[1], "-server")) {
server = true;
} else {
server = false;
}
if (server) {
run_server();
} else {
run_client();
}
printf("done\n");
enet_deinitialize();
return 0;
}
void run_server() {
ENetAddress address = {};
address.host = ENET_HOST_ANY;
address.port = 1234;
ENetHost *host = enet_host_create(&address, 4, 1, 0, 0);
if (!host) {
printf("Failed to create server\n");
}
printf("Server started...");
while (true) {
ENetEvent event;
while (enet_host_service(host, &event, 0)) {
switch(event.type) {
case ENET_EVENT_TYPE_CONNECT: {
printf("A client has connected!\n");
} break;
case ENET_EVENT_TYPE_RECEIVE: {
printf("Message recieved! %s\n", event.packet->data);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
printf("A client has disconnected\n");
break;
}
}
for (int i = 0; i < 4; i++) {
ENetPeer* peer = &host->peers[i];
if(peer->state == ENET_PEER_STATE_CONNECTED) {
auto packet = enet_packet_create("HELLO WORLD", strlen("HELLO WORLD"), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(peer, 0, packet);
}
}
Sleep(16);
}
enet_host_destroy(host);
}
void run_client() {
ENetAddress address = {};
address.host = ENET_HOST_ANY;
address.port = 1234;
ENetHost *host = enet_host_create(NULL, 4, 1, 0, 0);
enet_address_set_host(&address, "127.0.0.1");
address.port = 1234;
printf("Connecting to server\n");
auto peer = enet_host_connect(host, &address, 1, 0);
if (!host) {
printf("Failed to create client\n");
}
bool connected = false;
while (true) {
ENetEvent event;
while (enet_host_service(host, &event, 0)) {
switch(event.type) {
case ENET_EVENT_TYPE_CONNECT: {
printf("Connected to server\n");
connected = true;
} break;
case ENET_EVENT_TYPE_RECEIVE: {
printf("Message recieved! %s\n", event.packet->data);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
printf("A client has disconnected\n");
break;
}
}
if (connected) {
if(peer->state == ENET_PEER_STATE_CONNECTED) {
auto packet = enet_packet_create("HELLO WORLD", strlen("HELLO WORLD"), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(peer, 0, packet);
}
}
Sleep(16);
}
enet_host_destroy(host);
}
In client and server examples. the port is 7777, but the comment and puts info is 1234.
Is this a typo, perhaps?
Is there any plain to implement DTLS support ?
This repo is listed on npm as enet.c however it doesn't seem to be compatible with node-js natively. Is it intended to be used with emscripten?
I was looking through the flow to try to understand the timeout values supplied to enet_peer_timeout and I'm not understanding the purpose of timeoutMinimum. I traced a change back to commit f2c0ec3 where enet timeouts were changed from exponential back-off to a more linear approach and I viewed the linked cubik.org discussion and perhaps the change is fine, but I can't see the purpose of timeoutMinimum with that change as roundTripTimeout will never be greater/equal to roundTripTimeoutLimit unless timeoutLimit is 0 or 1 which I wouldn't think would be a valid case?
Perhaps I'm misunderstanding the purpose of this change? Thanks.
If you try to call:
enet_address_set_host_ip(address, "127.0.0.1")
then it will produce following IPv6 bytes:
{127, 0, 0, 1, 0, ...., 0}
And if pass this address to enet_host_create
then it will fail to create a host.
But if you call:
enet_address_set_host(address, "127.0.0.1")
or
enet_address_set_host(address, "localhost")
then it will resolve to:
{0, ...., 0, 255, 255, 127, 0, 0, 1}
and everything works fine.
Different code styles are scattered troughout the library
void someFunc() {
if (somCond) {
}
}
void someSecondFunc()
{
if (somCond) {
}
}
void someThirdFunc() {
if (somCond)
{
}
}
More inline documentation would be nice as well
What should happen: library should continue working and sending packets back and forth
What happens: library crashes application with malloc(): unaligned tcache chunk detected
Code to reproduce:
Server
#include <iostream>
#define ENET_IMPLEMENTATION
#define ENET_DEBUG
#include <enet.h>
int main()
{
ENetAddress address{};
address.host = ENET_HOST_ANY;
address.port = 3000;
ENetHost* host = enet_host_create(&address, 32, 2, 0, 0);
if(host == nullptr) {
return -1;
}
ENetEvent event;
int res = enet_host_service(host, &event, 0);
while(res >= 0 && true) {
switch(event.type) {
case ENET_EVENT_TYPE_CONNECT:
std::cout << "Connected!" << std::endl;
break;
case ENET_EVENT_TYPE_RECEIVE: {
std::cout << "Received packet!" << std::endl;
auto* data = new uint8_t[16];
ENetPacket* packet = enet_packet_create(data, 16, 0);
enet_peer_send(event.peer, 1, packet);
enet_packet_destroy(packet);
delete[] data;
enet_host_flush(host);
enet_packet_destroy(event.packet);
break;
}
case ENET_EVENT_TYPE_DISCONNECT:
std::cout << "Disconnect" << std::endl;
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
std::cout << "Disconnect timeout" << std::endl;
break;
case ENET_EVENT_TYPE_NONE:
break;
}
res = enet_host_service(host, &event, 0);
}
}
Client
#include <iostream>
#define ENET_IMPLEMENTATION
#define ENET_DEBUG
#include <enet.h>
#include <thread>
int main()
{
ENetAddress address{};
enet_address_set_host(&address, "127.0.0.1");
address.port = 3000;
ENetHost* host = enet_host_create(nullptr, 1, 2, 0, 0);
if(host == nullptr) {
return -1;
}
ENetPeer* peer = enet_host_connect(host, &address, 2, 0);
if(peer == nullptr) {
return -2;
}
bool connected = false;
ENetEvent event;
while(enet_host_service(host, &event, 0) >= 0) {
switch(event.type) {
case ENET_EVENT_TYPE_CONNECT:
std::cout << "Connected!" << std::endl;
connected = true;
break;
case ENET_EVENT_TYPE_RECEIVE:
std::cout << "Received packet!" << std::endl;
enet_packet_destroy(event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
std::cout << "Disconnect!" << std::endl;
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
std::cout << "Disconnect timeout!" << std::endl;
break;
case ENET_EVENT_TYPE_NONE:
break;
}
if(connected) {
for(int i = 0; i < 100; i++) {
auto* data = new uint8_t[16];
ENetPacket* packet = enet_packet_create(data, 16, 0);
enet_peer_send(peer, 0, packet);
delete[] data;
enet_packet_destroy(packet);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
return 0;
}
I'm using the latest enet.h
from the master branch. Below is a simple test.c
file to reproduce the error:
#define ENET_IMPLEMENTATION
#include "enet.h"
int main()
{
ENetPacket *packet = enet_packet_create("packet",
strlen("packet") + 1,
ENET_PACKET_FLAG_RELIABLE);
enet_packet_resize(packet, strlen("packetfoo") + 1);
}
Compile and run it, and then I encounter an error:
> gcc -I. -otest test.c && ./test
free(): invalid pointer
Aborted
Upon debugging and following the code, the error is triggered by enet_free(packet->data);
in enet_packet_resize
.
Lines 1401 to 1417 in 67178b0
The program tries to free packet->data
, but it is not the correct memory address allocated by enet_malloc
.
As seen in enet_packet_create
, the ENetPacket packet is allocated by enet_malloc
, and packet->data
is an offset of this address.
Lines 1374 to 1379 in 67178b0
The official ENet does not have this issue as packet->data
is allocated by enet_malloc
.
https://github.com/lsalzman/enet/blob/2a85cd64459f6ba038d233a634d9440490dbba12/packet.c#L19-L33
I also noticed issue #44. So, I think maybe enet_packet_resize
was intentionally removed initially.
Therefore, the solution may be to:
enet_packet_resize
and clearly document to users why this library does not provide it, as it saves one malloc call in enet_packet_create
.enet_packet_create
and enet_packet_resize
match.Hi,
I have a client/server application where each host has two channels, one for reliable packets and another for unreliable ones. On the unreliable channel i transmit about 3/kbps and the reliable channel is quite infrequent but occasional sees whole packets as large as 250 bytes. Trouble is that these "reliable" packets are frequently dropped, and I have no idea why as I'm testing over a local loopback and the throughput is obviously very small. If I raise the traffic on the unreliable channel a few times to eg 10/kbps virtually nothing gets through on the reliable channel. What gives?
int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
#ifdef _MSC_VER
if (inet_ntop(AF_INET6, (ENetAddress*)&address->host, name, nameLength) == NULL) {
#else
if (inet_ntop(AF_INET6, &address->host, name, nameLength) == NULL) {
#endif
return -1;
}
return 0;
}
Hello,
IN order to make the code compilable with MinGW-W64 in C++, two fixes are needed.
1 - IN enet.h:5103, a void* cast is required:
- if (inet_ntop(AF_INET6, &address->host, name, nameLength) == NULL) {
+ if (inet_ntop(AF_INET6, (void*)&address->host, name, nameLength) == NULL) {
Additionally, there are warnings if you compile with -Wextra, related to enum>integer conversions.
2- You need to make sure that _WIN32_WINNT >= 0x0600
#define _WIN32_WINNT 0x0600
This is because inet_ntop and inet_nton are only available since Windows Vista.
Of course, as a consequence, this library isn't compatible with Windows XP, but in 2021 this should no longer be a big problem...
Otherwise the library seem to work as well as the original ENet, both in IPv4 and IPv6. Thank you very much for this fork of ENet.
Hello,
I noticed defining ENET_FEATURE_ADDRESS_MAPPING switches between the new and old functions ( deprecated vs new ).
Should we define this for calling: enet_address_set_host ?
What should be the correct way of using this new feature? I assume sending in ipv4 address strings ( 127.0.0.1, localhost etc. ) will work since with ENET_FEATURE_ADDRESS_MAPPING defined it looks like the code will correctly map over to the new ipv6 format?
Thanks
While I fully support your idea of moving things forward with fresh codebase my concerns are about compatibility with original Enet protocol.
Few questions:
This is an honest question ; why break away from mainstream ENet and use your library? Very few care about ENet, but all who do will ask the same questions.
Will there be a performance cost
Will you commit to developing your extension to the same degree as the original? Why should we use your version without knowing it's not simply a pet project
will you actually be responsive to reasonable requests? Mainstream ENet strives for maturity yet ignores IPv6 as if it may be a passing craze.
Some embedded platforms only support ipv4 and most of the code seems to be based on AF_INET6. Please implement a define macro so that we can switch between ipv4 and ipv6.
In the securities technology system, generally the market data can be sent in multicast protocol to ensure the speed and fairness of transmission. Whether related use cases can be added to the test example?
Hi guys, currently in the latest version is it possible to increase the number of maximum connections on the server beyond 4096?
I am actually developing a game that need to host game servers in user side and the NAT are a problem. UPnP does not work on all routers (no all CPE routers have a public IP neither), so UDP hole punching will be a solution that can works.
I am implementing my own code for that purpose but will be great to have that already included on the library itself simplyfing the things and adding that support out of the box.
I want to suggest:
Than you for reading and for the interest of making this project.
Hi!
When calling enet_address_get_host_ip on ipv4 peer it returns the following string ::ffff:127.0.0.1
I made a fork of this demo application that shows how to scan peers in a LAN. The demo uses the original ENet.
In my fork I have added a CMake option to switch between original ENet and ZPL's ENet. With the original ENet it works, but with ZPL's ENet it fails with the error:
Failed to bind listen socket
We're planning to use ZPL's Enet on the DOSBox Staging project for serial, nullmodem, and softmodem transport, and hit some issues flagged by the PVS Studio static analyzer.
We want to follow whatever approach you'd prefer to get these fixed up. I can send them all in one ticket, or open one-by-one? Whatever is easier for you to track.
Dear contributors,
Not sure if it installation problem or the enet source code is a secrete in this new implementation?
I tried to install but get the following warning - and I cannot find the source code.
/home/xxx/workspace/enet/build
└── [email protected]
npm WARN enoent ENOENT: no such file or directory, open '/home/uta/workspace/enet/build/package.json'
npm WARN build No description
npm WARN build No repository field.
npm WARN build No README data
npm WARN build No license field.
Does this look expected? Is the reo library only? Is it possible to share the source code?
Thanks,
Carl
While I was testing with a small demo, I found enet_packet_resize is defined by not implemented in the single-header file enet.h.
Is there any special consideration for dropping the API?
Hello,
Due to these definitions [1] being present outside of the implementation (ENET_IMPLEMENTATION
), #include-ing enet.h
in multiple translation unit for the same project results in multiple definitions and a linker error [2].
The symbols have to be marked either static
(so that they keep internal linkage) or moved to the ENET_IMPLEMENTATION
of your single-header library.
[1]
Lines 214 to 219 in 5bd2ae5
[2]
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:217: multiple definition of `enet_v6_anyaddr'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:217: first defined here
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:218: multiple definition of `enet_v6_noaddr'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:218: first defined here
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:214: multiple definition of `enet_v4_anyaddr'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:214: first defined here
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:215: multiple definition of `enet_v4_noaddr'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:215: first defined here
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:216: multiple definition of `enet_v4_localhost'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:216: first defined here
[build] C:\msys64\mingw64\bin\ld: cmake/enet/libenet.a(server.c.obj):C:/***/lib/enet/include/enet.h:219: multiple definition of `enet_v6_localhost'; CMakeFiles\client.dir/objects.a(client.c.obj):C:/***/lib/enet/include/enet.h:219: first defined here
Cheers,
Alex.
using ENET_HOST_ANY, makes enet listen on the ipv6 device if available ( at least on linux )
this isn't a problem but i was wondering if there is a ENET_HOST_ANY_ variant that forces ipv4
I dont see one in the source, but i figure i could add it quite easily
*edit
further digging seems that ENetAddress expects an in6addr and seems to only support ipv6 now
In file included from enet_bug.c:4:
../../enet/include/enet.h: In function ‘enet_uint32 enet_peer_get_ip(ENetPeer*, char*, size_t)’:
../../enet/include/enet.h:3469:69: warning: ‘int enet_address_get_host_ip_old(const ENetAddress*, char*, size_t)’ is deprecated [-Wdeprecated-declarations]
return enet_address_get_host_ip(&peer->address, ip, ipLength);
^
In file included from enet_bug.c:4:
../../enet/include/enet.h:924:34: note: declared here
ENET_DEPRECATED(ENET_API int enet_address_get_host_ip_old(const ENetAddress * address, char * hostName, size_t nameLength));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../enet/include/enet.h:196:31: note: in definition of macro ‘ENET_DEPRECATED’
#define ENET_DEPRECATED(func) func __attribute__ ((deprecated))
^~~~
In file included from enet_bug.c:4:
../../enet/include/enet.h:3469:69: warning: ‘int enet_address_get_host_ip_old(const ENetAddress*, char*, size_t)’ is deprecated [-Wdeprecated-declarations]
return enet_address_get_host_ip(&peer->address, ip, ipLength);
^
In file included from enet_bug.c:4:
../../enet/include/enet.h:924:34: note: declared here
ENET_DEPRECATED(ENET_API int enet_address_get_host_ip_old(const ENetAddress * address, char * hostName, size_t nameLength));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../enet/include/enet.h:196:31: note: in definition of macro ‘ENET_DEPRECATED’
#define ENET_DEPRECATED(func) func __attribute__ ((deprecated))
^~~~
In file included from enet_bug.c:4:
../../enet/include/enet.h: In function ‘int enet_address_set_host_old(ENetAddress*, const char*)’:
../../enet/include/enet.h:5384:54: warning: ‘int enet_address_set_host_ip_old(ENetAddress*, const char*)’ is deprecated [-Wdeprecated-declarations]
return enet_address_set_host_ip(address, name);
^
../../enet/include/enet.h:5334:9: note: declared here
int enet_address_set_host_ip_old(ENetAddress *address, const char *name) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../enet/include/enet.h:5384:54: warning: ‘int enet_address_set_host_ip_old(ENetAddress*, const char*)’ is deprecated [-Wdeprecated-declarations]
return enet_address_set_host_ip(address, name);
^
../../enet/include/enet.h:5334:9: note: declared here
int enet_address_set_host_ip_old(ENetAddress *address, const char *name) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../enet/include/enet.h: In function ‘int enet_address_get_host_old(const ENetAddress*, char*, size_t)’:
../../enet/include/enet.h:5413:66: warning: ‘int enet_address_get_host_ip_old(const ENetAddress*, char*, size_t)’ is deprecated [-Wdeprecated-declarations]
return enet_address_get_host_ip(address, name, nameLength);
^
../../enet/include/enet.h:5387:9: note: declared here
int enet_address_get_host_ip_old(const ENetAddress *address, char *name, size_t nameLength) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../enet/include/enet.h:5413:66: warning: ‘int enet_address_get_host_ip_old(const ENetAddress*, char*, size_t)’ is deprecated [-Wdeprecated-declarations]
return enet_address_get_host_ip(address, name, nameLength);
^
../../enet/include/enet.h:5387:9: note: declared here
int enet_address_get_host_ip_old(const ENetAddress *address, char *name, size_t nameLength) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
When trying to use enet with various memory leak tools, they break enet when redefining 'malloc' and 'free'. Replacing the definitions in ENetCallBacks with 'emalloc' and 'efree' (and related locations in the code) fixes it.
(Specifically, MemWatch: http://www.linkdata.se/sourcecode/memwatch/ )
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.