fabienrousseau / flutter_pcsc Goto Github PK
View Code? Open in Web Editor NEWA Flutter plugin for using PCSC smartcard readers on Windows/macOS/Linux.
A Flutter plugin for using PCSC smartcard readers on Windows/macOS/Linux.
`Launching lib/main.dart on macOS in debug mode...
Running pod install...
CocoaPods' output:
↳
Preparing
Analyzing dependencies
Inspecting targets to integrate
Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)
Finding Podfile changes
- FlutterMacOS
- flutter_pcsc_macos
Fetching external sources
-> Fetching podspec for `FlutterMacOS` from `Flutter/ephemeral`
-> Fetching podspec for `flutter_pcsc_macos` from `Flutter/ephemeral/.symlinks/plugins/flutter_pcsc_macos/macos`
Resolving dependencies of `Podfile`
Error output from CocoaPods:
↳
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin21/rbconfig.rb:230: warning: Insecure world writable dir /opt/homebrew/opt in PATH, mode 040777
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require': dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle, 0x0009): tried: '/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/lib/ffi_c.bundle' (no such file) - /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
from /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi.rb:5:in rescue in <top (required)>' from /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi.rb:2:in
<top (required)>'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
from /Library/Ruby/Gems/2.6.0/gems/ethon-0.15.0/lib/ethon.rb:3:in <top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' from /Library/Ruby/Gems/2.6.0/gems/typhoeus-1.4.0/lib/typhoeus.rb:2:in
<top (required)>'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:440:in download_typhoeus_impl_async' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:372:in
download_and_save_with_retries_async'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:365:in download_file_async' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:338:in
download_file'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:53:in refresh_metadata' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source.rb:31:in
initialize'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:30:in initialize' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:315:in
new'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:315:in block in source_from_path' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:322:in
source_from_path'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in block in aggregate_with_repos' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
map'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in aggregate_with_repos' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:26:in
aggregate'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:60:in all' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface/error_report.rb:173:in
repo_information'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface/error_report.rb:77:in stack' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface/error_report.rb:24:in
report'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/command.rb:66:in report_error' from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:396:in
handle_exception'
from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:337:in rescue in run' from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:324:in
run'
from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/command.rb:52:in run' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/bin/pod:55:in
<top (required)>'
from /usr/local/bin/pod:23:in load' from /usr/local/bin/pod:23:in
require': cannot load such file -- 2.6/ffi_c (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/ethon-0.15.0/lib/ethon.rb:3:in
<top (required)>'require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:440:in
download_typhoeus_impl_async'download_and_save_with_retries_async' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:365:in
download_file_async'download_file' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:53:in
refresh_metadata'initialize' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:30:in
initialize'new' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:315:in
block in source_from_path'source_from_path' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
block in aggregate_with_repos'map' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
aggregate_with_repos'aggregate' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:60:in
all'repo_information' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface/error_report.rb:77:in
stack'report' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/command.rb:66:in
report_error'handle_exception' from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:337:in
rescue in run'run' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/command.rb:52:in
run'<top (required)>' from /usr/local/bin/pod:23:in
load'<main>' /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require': dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle, 0x0009): tried: '/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/lib/ffi_c.bundle' (no such file) - /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi_c.bundle (LoadError)require' from /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.4/lib/ffi.rb:5:in
rescue in <top (required)>'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/ethon-0.15.0/lib/ethon.rb:3:in
<top (required)>'require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:440:in
download_typhoeus_impl_async'download_and_save_with_retries_async' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:365:in
download_file_async'download_file' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:53:in
refresh_metadata'initialize' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:30:in
initialize'new' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:315:in
block in source_from_path'source_from_path' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
block in aggregate_with_repos'map' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
aggregate_with_repos'aggregate' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:60:in
all'source_with_url' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/sources_manager.rb:22:in
find_or_create_source_with_url'block in sources' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:177:in
map'sources' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:1077:in
block in resolve_dependencies'section' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:1076:in
resolve_dependencies'analyze' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer.rb:416:in
analyze'block in resolve_dependencies' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface.rb:64:in
section'resolve_dependencies' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer.rb:161:in
install!'run' from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:334:in
run'run' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/bin/pod:55:in
<top (required)>'load' from /usr/local/bin/pod:23:in
'require': cannot load such file -- 2.6/ffi_c (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/ethon-0.15.0/lib/ethon.rb:3:in
<top (required)>'require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'<top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'require' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:440:in
download_typhoeus_impl_async'download_and_save_with_retries_async' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:365:in
download_file_async'download_file' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:53:in
refresh_metadata'initialize' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/cdn_source.rb:30:in
initialize'new' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:315:in
block in source_from_path'source_from_path' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
block in aggregate_with_repos'map' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:331:in
aggregate_with_repos'aggregate' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.11.2/lib/cocoapods-core/source/manager.rb:60:in
all'source_with_url' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/sources_manager.rb:22:in
find_or_create_source_with_url'block in sources' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:177:in
map'sources' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:1077:in
block in resolve_dependencies'section' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer/analyzer.rb:1076:in
resolve_dependencies'analyze' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer.rb:416:in
analyze'block in resolve_dependencies' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/user_interface.rb:64:in
section'resolve_dependencies' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/installer.rb:161:in
install!'run' from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:334:in
run'run' from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/bin/pod:55:in
<top (required)>'load' from /usr/local/bin/pod:23:in
'
Exception: Error running pod install
I found some issue with waitForCardPresent
on Mac so I open this ticket.
waitForCardPresent
method throws an error: type 'Null' is not a subtype of type 'int'
waitForCardPresent
readCard() async {
int ctx = await Pcsc.establishContext(PcscSCope.user);
print('Context: $ctx');
List<String> readers = await Pcsc.listReaders(ctx);
if (readers.isEmpty) {
print('Could not detect any reader');
} else {
String reader = readers[0];
print('Using reader: $reader');
await Pcsc.waitForCardPresent(ctx, reader); // <-------- This line throw error
CardStruct card = await Pcsc.cardConnect(
ctx, reader, PcscShare.shared, PcscProtocol.any);
var response = await Pcsc.transmit(card, [0xFF, 0xCA, 0x00, 0x00, 0x00]);
print('Response: ${hexDump(response)}');
await Pcsc.cardDisconnect(card.hCard, PcscDisposition.resetCard);
}
await Pcsc.releaseContext(ctx);
}
Error message:
flutter: Context: 2
flutter: Using reader: SONY FeliCa RC-S300/P
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'int'
#0 PCSCBinding.waitForCardPresent (package:flutter_pcsc_macos/src/pcsc_bindings.dart:149:9)
<asynchronous suspension>
#1 BootScreen.readCard (package:uniform_client_app_flutter/screens/boot.dart:37:7)
<asynchronous suspension>
I need event function like :
When using waitForCardPresent and waitForCardRemoved to detect the card automatically in a program, the reader gets stuck and can't do more than 5 operations. After 3-5 operations, it just locks up. Even when waiting in a different isolate, this issue still occurs. For example, if I wait for a card to be present, read 5-6 values, the program just halts and waits until the card is removed and then throws an exception about how it couldn't read the card because there is no card in there. But I can see that the waitForCardPresent ends and it detects the card. Issue only occurs after a few operations are made.
What is more interesting is that the code works in debug mode and doesn't work in production mode. I believe it might be caused by library bindings to the winscard.h (or maybe some compile options?). I tried to run a similar code in C while using the library winscard.h, and everything works fine there. Here is an overview of what I am doing:
I'm using Ubuntu Linux 22.04.3 LTS, but similar error occurs in the MAC OS version as well.
while (true) {
//Wait for a new card
await Pcsc.waitForCardPresent(readerContext, readerName);
final currentCard = await Pcsc.cardConnect(readerContext, readerName, PcscShare.shared, PcscProtocol.any);
final cardNUID = await _getCardNUID(currentCard);
sendPort.send(PcscCardInfo(currentCard, cardNUID.data)); //Communicate the message to outside of the isolate
//Wait for the current card to be removed
await Pcsc.waitForCardRemoved(readerContext, readerName);
sendPort.send(null); //Communicate the message to outside of the isolate
}
It works in an islotate on its own, and I've tried various different versions of this code. After calling any of the waitFor command, no other operation is possible. (After a few operations at first)
The dependency FFI 1.0.0 is old. I manually force ffi ^2.0.1 without problems...
hi, I have a question.
flutter_pcsc can implement on Android device ?
Is there anyway to get max tranceive length for nfc tags?
Thanks for develop this plugin.
Please help me to listen to the card serial number
for some ccid devices, we have to control it using escape channel.
and the PcscPlatform has only transmit method, so, how about add a escape() method?
just like
Future<List<int>> escape(
int hCard, List<int> commandBytes,
{bool newIsolate = false}) {
throw UnimplementedError('escapeCommand() has not been implemented.');
}
for flutter_pcsc_windows
@override
Future<List<int>> escape(
int hCard, List<int> commandBytes, { bool newIsolate = false}) {
return _binding.escapeCommand(hCard, commandBytes, newIsolate: newIsolate);
}
for pcsc_binds.dart
Future<Uint8List> escapeCommand(
int hCard, List<int> sendCommand,
{bool newIsolate = false}) {
if (newIsolate) {
return _escapeCommandInNewIsolate(hCard, sendCommand);
} else {
return _escapeCommandInSameIsolate(hCard, sendCommand);
}
}
Future<Uint8List> _escapeCommandInNewIsolate(
int hCard, List<int> sendCommand) {
return compute(_computeFunctionEscapeCommand, {
'h_card': hCard,
'command': sendCommand
});
}
Future<Uint8List> _escapeCommandInSameIsolate(
int hCard, List<int> sendCommand) {
var nativeSendCommand = _allocateNative(sendCommand);
var pcbRecvLength = calloc<DWORD>();
pcbRecvLength.value = PcscConstants.MAX_BUFFER_SIZE;
var pbRecvBuffer = calloc<ffi.Uint8>(pcbRecvLength.value);
// #define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(3500)
int dwControlCode = 0x310000 + 3500*4;
try {
var res = _nlwinscard.SCardControl(hCard, dwControlCode, nativeSendCommand.cast(),
sendCommand.length, pbRecvBuffer.cast(), pcbRecvLength.value, pcbRecvLength);
_checkAndThrow(res, 'Error while transmitting to ccid device');
Uint8List response = _asUint8List(pbRecvBuffer, pcbRecvLength.value);
return Future.value(response);
} finally {
calloc.free(nativeSendCommand);
calloc.free(pcbRecvLength);
calloc.free(pbRecvBuffer);
}
}
and when we connect a device, we should do
pcscCard = await Pcsc.cardConnect(pcscCtx, readerName, PcscShare.direct, PcscProtocol.undefined);
at the same time, a reset() method can be implemented to do a cold/warm reseting a card.
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.