Git Product home page Git Product logo

saucybot-discord's People

Contributors

chooks22 avatar delphox avatar dependabot[bot] avatar iirelu avatar ikanimew avatar renovate[bot] avatar sn0wcrack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

saucybot-discord's Issues

[BUG] Twitter embeds remain unreliable - consider always replacing

Describe the bug
This is more of a feature ask - but I wanted to start a discussion on if there's a way to make fixing twitter embeds more reliable. Right now if I'm looking at the check right, it seems it only replaces the embed if Discord failed to create one. Can we have an option for it to fix them in all instances so it achieves fixing broken Twitter embeds like vxtwitter, twxtter, or other similiar parent services?

To Reproduce
Any twitter link with a video. The embed may be successful in discord, but the video frequently fails to play from the twitter embed.

Expected behavior
An embedded video is created that can reliably be played in Discord.

Additional context
Open to other suggestions - I was just hoping this remained a reliable way to automatically convert twitter links to ones that played correctly in discord embeds.

[BUG] SaucyBot no longer adds embeds to Pluralkit/webhook messages

Context: PluralKit is another Discord bot which allows single users to send messages under multiple names through use of webhook messages, which it does by first reading the plain message sent by a user, then deleting that message and instantly recreating it with the webhook name.

Previously (before today), using this bot and SaucyBot in conjunction created no issues. If a user using PluralKit sent a message with a link to a supported website, SaucyBot would briefly attempt to create an embed for the user's initial message in the intervening second or two when the message existed, but would stop doing so after Pluralkit deleted said message. It would then continue onto create an embed for the webhook message Pluralkit had created to replace it. Screenshot of past instance when this previously worked:
image

However, for some unknown reason, the bot does not (at the time of writing) do this any longer. It instead attempts to create an embed for the initial message, and then stops when Pluralkit deletes the message. Pluralkit then continues onto recreate the message with the webhook name and profile, but SaucyBot does not attempt to create an embed from this message, as it did previously. Here is an example screen recording of the bot's current behavior:

2023-03-17.23-57-42.mp4

I have granted SaucyBot the administrator permission in the relevant server, so there should be no permissions issue stopping it from interacting with Pluralkit's messages as it did before.

[BUG] SaucyBot posts pics from only one link when multiple links are posted in the same post

Describe the bug
When more than one link is posted by a user at the same time in one post, SaucyBot only pulls and uploads picture from one of those links.

To Reproduce
Paste at least two links in one message and send them. Those may be from the same or different sites.

Expected behavior
SaucyBot pulls and uploads images from every link posted.

Additional context
The original saucebot had that feature, therefore I figured I'd report it as a bug.
Issue was checked by posting double or mixed links from DeviantArt, FurAffinity and Pixiv
The bot seems to prioritize DeviantArt

[BUG] Bot needs Manage Webhooks permission to respect Twitter embeds

Describe the bug
Bot removes Twitter embeds after posting its own embed, but is only able to do so when Manage Webhooks is enabled for the bot.

To Reproduce
Disable "Manage Webhooks" for @everyone and leave it off for SaucyBot, then post a Twitter link.

Expected behavior
SaucyBot should request Manage Webhooks permissions when added to a server to prevent this issue. Ideally, if the permission was denied and Saucy is unable to delete an embed because of it, the bot should indicate somehow that it needs this permission to function properly. Even more ideally, the embed deletion feature should be toggleable.

Additional context
Image of example behavior. SaucyBot deletes the Twitter default embed if Manage Webhooks is on.
Screen Shot 2024-06-01 at 6 16 49 PM

can the bot be given permission to delete messages?

Is it possible to make Saucybot delete the users message after fetching the file(s) and posting the embed?
because otherwise, it's just doubling the amount of messages and clogging up the channels, especially since it works now without even using the command prompt so it's doing it's thing even when people don't intentionally use it.

[BUG] Bot prioritizes videos of quote reply over content of the posted tweet on twitter

Describe the bug
When bot tries to process a tweet that is a quote retweet reply to another post, if the replied to tweet includes a video, the bot will embed the quoted tweet instead of linked tweet media

To Reproduce
Example of tweet where the issue occurs (NSFW, not porn, but still nsfw): https://twitter.com/303_taroo/status/1763652002482188613

Expected behavior
Embeded media should be the images of the quote reply.

Feature request: DeviantArt support

The original Saucebot supports DeviantArt, but this one doesn't. I was planning to migrate to this bot and lack of this one feature is a problem for me. Can it be added?

Fix 'ghost' messages / make the 'matched, please wait' message optional

While waiting to see if an embed works or not SaucyBot posts a message like this,
Discord_TCYERbeEAg_03_27_2040

If you aren't looking at the channel at the moment this message is posted and then deleted, it leaves you with a 'ghost' unread message notification on the channel until you right click the channel and mark it as read.
image

If there's any way to silence this single message in the process per-server that'd be rad

FurAffinity descriptions are given many excess blank lines.

Describe the bug
When SaucyBot creates an embed for a FurAffinity post, it adds an extra blank line between every line in the description.

To Reproduce
Paste this into a Discord message: https://www.furaffinity.net/view/51719696/

Expected behavior
The description should look like what fxfurafinity embeds:
fxFA

Instead, it looks like this:
SaucyFA

Additional context
It looks like the parser is just accidentally adding a blank line after every single line in the original description. Should be a fairly simple fix.

Feature request: Saucybot deletes the user's original Twitter video message and preserves the link to the original tweet

Hi Sn0wCrack, the community I'm a part of recently added saucybot-discord to our Discord. While we love finally being able to play Twitter videos in Discord again (thank you for your work on it!), it's kind of clunky to have Discord embed the tweet with the video thumbnail and then have the video below it.

The workflow that some people end up doing is:

  1. Post the link to the tweet
  2. Let saucybot grab the video and send the embedded video as a message
  3. Delete their own post, leaving no trace of the source tweet

As someone in the community I'm in so elegantly put it, "what if i wanna see the mf's tweet ๐Ÿ˜‚"

If you have the time to work on this, would you be able to have saucybot delete the user's original post and then include the link to the tweet in question with the newly-embedded video?

Is there a command to configure X on each site?

been looking through the bot and was wondering if there's a command to change the amount of images it embeds directly on discord. Is it a feature ? or do i have to deploy the bot myself and edit the file on my pc?

Saucybot doesn't embed Pixiv links [BUG]

Since yesterday Saucy isn't embedding Pixiv links, pasting the link gets the message that Saucybot is matching the links but then it doesn't do anything and only leaves the link as typed. Saucy works normally with Devianart, Twitter, Newgrounds, and Artstation.

Oddly enough, I tried adding it to a dummy server I have to test bots and it works there perfectly, I tried matching the permissions between the two, and still doesn't work in my main server.

[BUG] twitter changing to x.com so embed fix no longer works

twitter is switching their links to x.com. can the bot fix the embeds for x the same way it has for twitter? the vx creator has made fixv to work with x so it should all work the same way. aka

twitter.com -> vxtwitter.com
x.com -> fixvx.com

Devient Art Links Stop Working

Describe the bug
When it comes to Devient art links, the bot doesn't seem to work anymore. There will be flash of it trying, but then nothing. It still works with other links like Twitter or FurAffinity, its just DA it seems to not work with

To Reproduce
Just post a devient art link

Expected behavior
there will be a flash of it replying, and then nothing

Additional context

FEEDBACK REQUESTED: Twitter NSFW Video and Twitter Failed Embeds Support

Now that I'm hoping I've got the bugs ironed out on that one.

I'd like to hear from people over the next couple of weeks as to what they think of this feature and how useful it seems to them.

I'm personally thinking of disabling this, but if enough people find this more useful than annoying, I'm more than willing to keep it enabled on the live version of SaucyBot.

Please let me know what you think in a reply here or by joining the SaucyBot Support Discord Server

[Request] A config to disable Twitter video upload

Our server already uses BDSMbed to link twitter video uploads directly so they play inline on mobile and web discord, and it makes no distinction between NSFW or not (since it doesn't matter for the library they use to fetch the video links). This in combination with Saucybot causes double uploads when the URL in question is detected as NSFW.

A setting to disable video uploads from the bot would be a simple way to work around this scenario.

Feature Request: Allow users to delete bot embeds to their links

At rare occasions the link will be embedded properly, but the bot will still add a second embed, pretty much duplicating the message.
At other situations, the user specifically posts a link not wanting it to embed (for example nsfw content in a safe channel), but there is no way to stop the bot from embedding.
More commonly a user will post a link in the wrong channel, and even if they delete their message, the embed will remain.
In situations like this, only a mod can delete the mistake and mods are simply not always available.

There needs to be a way for all users to delete embeds of their own links. A suggestion is to use a specific reaction emote (for example โŒ) that instructs the bot to delete the message if it's triggered by the message author.

[NEW SITE] misskey.design

Site Name: Misskey.design

Site URL: https://misskey.design/

Example URLs:

From what I have seen, misskey.design URLs will embed properly on Discord if they contain one or multiple images, one or multiple animated GIFs, but not a video. This is what motivates this request.

As far as I know, misskey.design is based on Misskey, so I would assume at least some of the work for misskey.io support could prove useful for misskey.design.

[NEW SITE] misskey.io

Site Name:
Misskey

Site URL:
https://misskey.io/

Example URLs:

Misskey API Docs:
https://misskey-hub.net/en/docs/api/

Further information:
misskey.io is a site where a lot of JP artists migrated to, part of the fediverse. It doesn't provide NSFW embeds.

I'm currently running the very simple Discord embed helper for this site where you replace the .io with .wtf, and it creates vxtwitter-like embeds for Discord, which allows embeds of NSFW content.
The example output is pretty much 1:1 the HTML output of vxtwitter, you can check it by going to view-source:https://misskey.wtf/notes/9lbmhln1jb for example. The note ID is always an alphanumeric string between 10 and 16 characters (so far).
This is in PHP, nothing special, very barebones but gets the job done.
I thought about just making a PR with the site added but since I don't know C# and haven't worked with actual software before, I lack the skills to do it myself.

I hope this helps!

Basically fetching the API result of a /api/notes/show request:

// If the renoteId key exists, this is a renote of a note
if (isset($result->renoteId) && !empty($result->renoteId)) {
	// grab the information of the renoted note and reassign the ID, we don't care about the renote info
	$result = $result->renote;
	$noteID = $result->id;
}
// Grab some basic information with fallbacks where appropriate
$displayName = $result->user->name ?? $result->user->username;
$userName = $result->user->username;
$avatar = $result->user->avatarUrl ?? '/noavatar.jpg';
$text = $result->text ?? "no text";
$date = $result->createdAt;

if (!isset($result->files)) die("Note missing files");

$files = $result->files;
if (sizeof($files) === 0) die("No files");

// if only 1 file of type image/gif, grab its url. There's also a thumbnailUrl key containing a reduced size webp version of a gif but discord does not support webps
if (sizeof($files) === 1 && $files[0]->type === 'image/gif') {
	$imageURL = $files[0]->url;
// same for video, but the HTML output changes accordingly
} elseif (sizeof($files) === 1 && $files[0]->type === 'video/mp4') {
	$videoURL = $files[0]->url;
	goto video;
} else {
	// Check if the thumbnail hasn't been stored before, store a reduced version when not
	if (!file_exists("./thumbnails/".$noteID.".jpg")) {
		// Similar to vxtwitter, create a mosaic of all images in the note, but not as fancy
		try {
		$imagick = new Imagick();
		$count = 0;
		foreach ($files as $file) {
			$imagick->addImage(new imagick($file->thumbnailUrl));
			$count++;
		}
		$cols = (int)sqrt($count);
		$rows = (int)ceil($count / (float)$cols);
		$result = $imagick->montageImage(new ImagickDraw(), $rows."x".$cols."+0+0", "", Imagick::MONTAGEMODE_UNFRAME, "0x0+0+0");
		$result->setImageFormat('jpg');
		$result->setImageCompressionQuality(80);
		file_put_contents("./thumbnails/".$noteID.".jpg", $result);

		} catch (Exception $exception) {
			die($exception);
		}
	}
	$imageURL = "/thumbnails/".$noteID.".jpg";
}
// Then here the HTML headers get created containing all the information from the note

The oembed.json in the HTML is a PHP file in a folder called oembed.json which just passes back the info we give it as a json:

<link rel="alternate" href="/oembed.json?author_name=<?= urlencode($displayName ?? "") ?>%20(@<?= urlencode($userName ?? "") ?>)&author_url=<?= urlencode("https://misskey.io/notes/".($noteID ?? "")) ?>&provider_name=Misskey.io&provider_url=https://misskey.io" type="application/json+oembed" title="<?= urlencode($userName ?? "") ?>">
// /oembed.json/index.php
if (empty($_GET)) die();
$data = [];
foreach ($_GET as $param => $value) {
    $data[$param] = $value;
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
die();

[BUG] Twitter video embed

So Saucy bot stopped download and embed Twitter videos to server because of Twitter god awful API. have u been able to work around this yet? ๐Ÿฅบ

Furaffinity posts wont work.[BUG]

When posting links from Furaffinity the bot replies with
"Matched link to FurAffinity, please wait..."
But it gets stuck there and never posts the image.

The issue has been present for over a week now.
All other sites work as expected.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

docker-compose
SaucyBot/docker-compose.dev.yml
  • mariadb 11@sha256:e59ba8783bf7bc02a4779f103bb0d8751ac0e10f9471089709608377eded7aa8
  • redis 7-alpine@sha256:0bc09d9f486508aa42ecc2f18012bb1e3a1b2744ef3a6ad30942fa12579f0b03
SaucyBot/docker-compose.prod.yml
  • mariadb 11@sha256:e59ba8783bf7bc02a4779f103bb0d8751ac0e10f9471089709608377eded7aa8
  • redis 7-alpine@sha256:0bc09d9f486508aa42ecc2f18012bb1e3a1b2744ef3a6ad30942fa12579f0b03
dockerfile
SaucyBot/Dockerfile
  • mcr.microsoft.com/dotnet/runtime 8.0-alpine3.19@sha256:6c3def5f3ab3f1f1cdf9320f351b15e200dca527212733dab7eb404bff1dbb21
  • mcr.microsoft.com/dotnet/sdk 8.0-alpine3.19@sha256:b1275049a8fe922cbc9f1d173ffec044664f30b94e99e2c85dd9b7454fbf596c
github-actions
.github/workflows/continuous-deployment.yml
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • docker/metadata-action v5@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
  • docker/setup-qemu-action v3@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf
  • docker/setup-buildx-action v3@aa33708b10e362ff993539393ff100fa93ed6a27
  • docker/login-action v3@9780b0c442fbb1117ed29e0efdff1e18412f7567
  • docker/build-push-action v6@5176d81f87c23d6fc96624dfdbcd9f3830bbe445
  • appleboy/ssh-action v1.0.3@029f5b4aeeeb58fdfe1410a5d17f967dacf36262
.github/workflows/continuous-integration.yml
  • actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
  • actions/setup-dotnet v4@6bd8b7f7774af54e05809fcc5431931b3eb1ddee
  • actions/cache v4@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
nuget
SaucyBot.Tests/SaucyBot.Tests.csproj
  • coverlet.collector 6.0.2
  • xunit.runner.visualstudio 2.8.2
  • xunit 2.9.0
  • NSubstitute 5.1.0
  • Microsoft.NET.Test.Sdk 17.10.0
SaucyBot/SaucyBot.csproj
  • Xabe.FFmpeg 5.2.6
  • StackExchange.Redis 2.8.0
  • Serilog.Sinks.Console 6.0.0
  • Serilog.Settings.Configuration 8.0.2
  • Serilog.Extensions.Hosting 8.0.0
  • Serilog 4.0.1
  • Pomelo.EntityFrameworkCore.MySql 8.0.2
  • Polly.Core 8.4.1
  • Microsoft.Extensions.Hosting 8.0.0
  • Microsoft.Extensions.Caching.StackExchangeRedis 8.0.7
  • Microsoft.Extensions.Caching.Memory 8.0.0
  • Microsoft.EntityFrameworkCore.Tools 8.0.7
  • Microsoft.EntityFrameworkCore.Sqlite 8.0.7
  • Microsoft.EntityFrameworkCore.Design 8.0.7
  • Microsoft.EntityFrameworkCore 8.0.7
  • EFCore.NamingConventions 8.0.3
  • Discord.Net 3.15.3
  • AngleSharp 1.1.2
global.json
  • dotnet-sdk 8.0.303

  • Check this box to trigger a request for Renovate to run again on this repository

Twitter Image Reposts

Bot reposts twitter posts when the picture embed takes "too long" (half a second), resulting in multiple reposts. It also only posts a single image from a multi-image tweet.

[BUG] Saucybot doesn't embed Pixiv links

Saucy isn't embedding Pixiv links, pasting the link gets the message that Saucybot is matching the links but then it doesn't do anything and only leaves the link as typed. Saucy works normally with Devianart, Twitter, Newgrounds, and Artstation.

I already tried kicking the bot and inviting it back and changing permissions, but the issue persists. and unlike the previous time something like this happened, changing the server's name didn't fix the issue.

[BUG] Error [ShardingReadyDied]

Describe the bug
Bit of a noob, especially with docker, so I'm sure this is probably my fault in some way, but I'm stuck trying to deploy this thing and googling errors hasn't been much help.

The fields in the .env file I've left blank are either websites I don't want to include with the bots functionality, or not being sure what value should be applied.

After running docker compose up, everything seems to start up as expected, but when it tries to connect to a shard, I get a 403.

I've invited the bot to my server with the bot and applications.commands scopes, as well as all Privileged Gateway Intents enabled and Text Permissions Send Messages, Embed Links, Attach Files and Read Message History.

To Reproduce

Create .env file like below, run docker compose up.

Expected behavior

Bot coming online and functioning.

Additional context

.env file:

NODE_ENV=production

DISCORD_API_KEY=[CENSORED]
DISCORD_SHARD_RESPAWN=true
DISCORD_SHARD_SPAWN_TIMEOUT=30000

DISCORD_GUILD_ID= # For development only
DISCORD_CLIENT_ID= # For development only

MAXIMUM_EMBEDS=8
DISABLED_SITES=

SENTRY_DSN=
REDIS_URL=

PIXIV_LOGIN=
PIXIV_PASSWORD=
PIXIV_COOKIE=
PIXIV_POST_LIMIT=5
PIXIV_UGOIRA_FORMAT=mp4
PIXIV_UGOIRA_BITRATE=2000

ARTSTATION_POST_LIMIT=5

FA_COOKIE_A=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx [OBFUSCATED TO SHOW SYNTAX BEING USED]
FA_COOKIE_B=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx [OBFUSCATED TO SHOW SYNTAX BEING USED]

EHENTAI_IPB_ID=
EHENTAI_IPB_PASS=

TWITTER_API_KEY=[CENSORED]
TWITTER_API_SECRET=[CENSORED]
TWITTER_ACCESS_TOKEN=[CENSORED]
TWITTER_ACCESS_SECRET=[CENSORED]
TWITTER_BEARER_TOKEN=[CENSORED]
TWITTER_READ_DELAY=1350

DEVIANTART_CLIENT_ID=
DEVIANTART_CLIENT_SECRET=

Log output:

saucybot-discord-cache-1  | 1:M 18 Sep 2022 15:39:53.364 * Ready to accept connections
saucybot-discord-bot-1    | [2022-09-18 15:39:55] [Manager] [INFO] Launched Shard 0
saucybot-discord-bot-1    | node:internal/process/promises:279
saucybot-discord-bot-1    |             triggerUncaughtException(err, true /* fromPromise */);
saucybot-discord-bot-1    |             ^
saucybot-discord-bot-1    |
saucybot-discord-bot-1    | [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Response code 403 (Forbidden)".] {
saucybot-discord-bot-1    |   code: 'ERR_UNHANDLED_REJECTION'
saucybot-discord-bot-1    | }
saucybot-discord-bot-1    | [2022-09-18 15:40:00] [Manager] [ERROR] Shard 0's process exited before its Client became ready.
saucybot-discord-bot-1    | node:internal/process/promises:279
saucybot-discord-bot-1    |             triggerUncaughtException(err, true /* fromPromise */);
saucybot-discord-bot-1    |             ^
saucybot-discord-bot-1    |
saucybot-discord-bot-1    | [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Response code 403 (Forbidden)".] {
saucybot-discord-bot-1    |   code: 'ERR_UNHANDLED_REJECTION'
saucybot-discord-bot-1    | }
saucybot-discord-bot-1    | /bot/node_modules/discord.js/src/sharding/Shard.js:162
saucybot-discord-bot-1    |         reject(new Error(ErrorCodes.ShardingReadyDied, this.id));
saucybot-discord-bot-1    |                ^
saucybot-discord-bot-1    |
saucybot-discord-bot-1    | Error [ShardingReadyDied]: Shard 0's process exited before its Client became ready.
saucybot-discord-bot-1    |     at Shard.onDeath (/bot/node_modules/discord.js/src/sharding/Shard.js:162:16)
saucybot-discord-bot-1    |     at Object.onceWrapper (node:events:628:26)
saucybot-discord-bot-1    |     at Shard.emit (node:events:513:28)
saucybot-discord-bot-1    |     at Shard.emit (node:domain:489:12)
saucybot-discord-bot-1    |     at Shard._handleExit (/bot/node_modules/discord.js/src/sharding/Shard.js:408:10)
saucybot-discord-bot-1    |     at ChildProcess.emit (node:events:513:28)
saucybot-discord-bot-1    |     at ChildProcess.emit (node:domain:489:12)
saucybot-discord-bot-1    |     at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
saucybot-discord-bot-1    | Emitted 'error' event on Shard instance at:
saucybot-discord-bot-1    |     at /bot/node_modules/discord.js/src/sharding/Shard.js:416:56
saucybot-discord-bot-1    |     at processTicksAndRejections (node:internal/process/task_queues:96:5) {
saucybot-discord-bot-1    |   code: 'ShardingReadyDied'
saucybot-discord-bot-1    | }
saucybot-discord-bot-1 exited with code 1

Invite link fails to work

Attempted to invite the bot to multiple servers I am an admin in, or I own, and the invite failed, presenting this screen:
chrome_lHzhkszyi5

I am an adminstrator in all of the discords, and I tried making a role with the specific requested permission enabled and that also failed to work. Figured I should report this since this bot's functionality would be very useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.