Giter Club home page Giter Club logo

valheim-discordconnector's Introduction

Discord Connector

CodeQL Build Publish GitHub release (latest by date) Thunderstore.io NexusMods Built against Valheim version

Connect your Valheim server to Discord. (See website for installation or configuration instructions). This plugin is largely based on valheim-discord-notifier, but this plugin supports randomized messages, muting players, and Discord message embeds.

Plugin Details

See the README for the plugin.

Changelog

See the changelog.

Building

Before building, you must update the GameDir property in the csproj file.

Use dotnet to restore and build the project. Post build, the compiled library and its dependencies get copied into bin/DiscordConnector which enables you to simply copy that folder into $(GameDir)/BePinEx/plugins for testing.

The compiled plugin will be in a zip ready for upload at bin/DiscordConnector.zip.

Dependencies

For JSON serialization, using Newtonsoft.Json

For data storage/retrieval using LiteDB (If you want to read the database file generated, you can use LiteDB Studio)

Contributors

Thanks for the helpful contributions!

  • @Digitalroot
  • @nwesterhausen
  • @thedefside

Thanks for an excellent original plugin @aequasi!

valheim-discordconnector's People

Contributors

dependabot[bot] avatar digitalroot avatar nwesterhausen avatar renovate[bot] avatar thedefside 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

Watchers

 avatar  avatar  avatar  avatar

valheim-discordconnector's Issues

Leaderboard issues

Since updating to 1.2.0, I'm having 3 issues with the leaderboard:

  1. Stats are not updating
  2. The names are missing from the embedded message
  3. I have disabled Pings and Shouts, yet they still appear

image

I have attached all the config and record files.
discordconfig.zip

Changes in Toggles config is ignored

[Toggles.Messages]

## If enabled, this will send a message to Discord when the server launches.
# Setting type: Boolean
# Default value: true
Server Launch Notifications = false

## If enabled, this will send a message to Discord when the server has loaded the map and is ready for connections.
# Setting type: Boolean
# Default value: true
Server Loaded Notifications = false

## If enabled, this will send a message to Discord when the server begins shut down.
# Setting type: Boolean
# Default value: true
Server Stopping Notifications = false

## If enabled, this will send a message to Discord when the server has shut down.
# Setting type: Boolean
# Default value: true
Server Shutdown Notifications = false

## If enabled, this will send a message to Discord when the server saves the world.
# Setting type: Boolean
# Default value: true
Server World Save Notifications = false

But every time someone joins, Discord is still getting spammed.
NtVcwpw

Is there not a flag for the startup message?

Send message with public IP and running Port

Dens92 on NexusMods:

Hello, thank you very much for your work and evolution of the mod in such a short time.

I have a mechanic that I wish you could add, if there is a way.I would like the bot to start the server also notify the IP and Port in which the server is running at the moment.

What for? Well, I have my server hosted on a second home PC, using Steam's Valheim Dedicated Server, and every time I restart my modem, the public IP of my team changes, therefore of the server, to which I must notify the players every day the IP In use.

guilded.gg webhook support

Requested on NexusMods. Some documentation I found here.

Looks very similar and it may work out of the box but it should be easy to make a change to the payload if we detect the webhook to be for guilded.gg

[Toggles.Stats] ## Could collecting and sending be two seperate things?

Current:
// If enabled, will collect and enable sending player %%%%% statistics.

Proposed:
// If enabled, will allow the collection of all player statics for the leaderboard
// Disabling this disables the leaderboard

// If enabled, will enable the sending of player %%%%% statistics to the leaderboard

Reasoning:
Could only set deaths=true, but if the admin decides later to include other statistics, they wont be starting from zero...
also, could be used for a moderation standpoint to see who is excessively pinging/shouting even if those arent being sent

EDIT:
the pound signs make things look like giant headers, so changing them to // for this example

Event messages not being sent

I have Discord Connector 1.2.1 installed, and the event messages turned on, but I have never gotten any messages regarding events. We have had several raids since I updated. I do have Custom Raids mod installed. Not sure if that is conflicting with your patch or not.
discordsettings.zip

Make web requests async

while we are on topic, theres another issue i was going to mention as well. i was following a discussion in discord about why someone said they wouldnt use your mod, and the coder person said "it's not async and the timeout is way too high. if discord fails to reply for whatever reason, the discord connector blocks the server, until all connected players time out."
and then another coder replied "he didn't put webrequest into async? i mean task* ...nvm, i see it now lol. well yeah true, i guess it was hard to write Task.Run"

image

idk bc im not a coder, but i have seen a lot of the big servers refuse to use your mod, and apparently this above is the reason. me personally i love the functionality of the mod and it works great for me, but i have good hardware, superb internet, and only maybe 25 players so i never run into this issue. but sometimes people DC when connected to my server so who knows. anyyway, maybe you can look into it and decide if its a problem. i hope this is well received, im only sharing what i read because id like to see your mod be the best it can be. thx for all the hard work you put in, its very much appreciated.

sry if maybe i shoulda put this in a separate thread...

Originally posted by @PaloAlo in #117 (comment)

BUG | Events: - not all messages & wrong messages & some event area coordinates are 0.0, 0.0, 0.0 on dedicated

No event start message (it rested first?)
The second message didn't have anything on the dedicated, and dedicated had no coordinates

I think I read in one of your updates you removed %PLAYERS% so ignore my lack of deleting it from the messages =]

Here are settings from games.nwest.valheim.discordconnector-messages.cfg

Event Start Message = ⚡ %VAR1% Event: %EVENT_MSG% around %PLAYERS%
Event Stop Message = ⚡ %VAR1% Event: %EVENT_MSG%
Event Paused Message = ⚡ %VAR1% Event: %EVENT_END_MSG% -- for now! (Currently paused due to no players in the event area.)
Event Resumed Message = ⚡ K%VAR1% Event: %EVENT_START_MSG% around %PLAYERS%

In Discord from dedicated server:
Today at 8:53 PM
⚡ Könnunsvefnð Event: The forest rests again around %PLAYERS%
Coords: (305.5, 76.7, 484.6)
8:55
⚡ Könnunsvefnð Event:
Coords: (0.0, 0.0, 0.0)

In Discord from local player:
Today at 8:53 PM
⚡ LocalDC Event: The forest rests again around %PLAYERS%
Coords: (305.5, 76.7, 484.6)
8:55
⚡ LocalDC Event: The forest is moving...
Coords: (305.5, 76.7, 484.6)

I was looking in the logs for a clue of what was sent when, but didn't see anything (maybe if/when you add a debug option I can provide more)

Feature Request -Unique players & active players board

A board that posts periodically the number of unique players on the ever server, how many have been active that day (maybe week & month too?), And how many are online right now

Example:

SERVER PLAYERS
Online now: 4
Today: 8
Week: 29
Month: 31
Total Unique: 42
Most at once: 17

feature request - filter messages

I was going through the change-log looking for it, but didn't read anywhere that filtering messages was available. That would be the main reason for us to switch out what we are currently using. This one we have is supposed to, but is failing.

We have zones and sleep mods shouting into our discord where we don't want to see them, so if you could add a configurable filter to apply before messages are sent, that would be awesome!

If this is already a current feature, please let us know =]

send in-Game chat

ttestbetterthanftest on NexusMods:

do you think it would be possible to report on discord the conversation of the inGame chat?

cron schedule expressions instead of minutes

Not sure when it does the leader-boards exactly. If set to 720 minutes, does that mean it wont do the first one until 12 hours after the time I last started the server?; Meaning that it could possibly go days without a leader-board post if the server is restarted?

Would it be easy to switch from minutes to cron schedule expressions?

0 6,18 * * *
https://crontab.guru/#0_6,18___*

This way we could have the leader-boards post at specific times even if the servers restart... It wouldn't be limited to an interval either then; Could easily do 08:30 and 17:15 using cron schedule expressions (I would just include a link to https://crontab.guru for those unfamiliar)

EDIT: with this I could even set it up so it only does it on Wednesdays and Sundays at noon which would be amazing
0 12 * * 3,7

Gendered Messages based on Player Skin

lime1811 on Nexus:

Cool mod, if you can find out the gender of the character (male, female). I want to split messages for different genders "Player join".

multiple event notifications - doesn't seem to respect position toggle when using fancy embeds

Sorry to be that guy this morning lol. Since removing the corrupted records file, I've got my notifications back but event notifications are coming through multiple times.

[9:16 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down
[9:16 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down
Coordinates
(213.7, 33.4, -365.1)
[9:16 AM] 
BOT
 Valheim Server Status: Event: Eikthyr rallies the creatures
[9:16 AM] 
BOT
 Valheim Server Status: Event: Eikthyr rallies the creatures
Coordinates
(213.7, 33.4, -365.1)
[9:16 AM] 
BOT
 Valheim Server Status: Event: Eikthyr rallies the creatures — for now! (Currently paused due to no players in the event area.)
[9:16 AM] 
BOT
 Valheim Server Status: Event: Eikthyr rallies the creatures — for now! (Currently paused due to no players in the event area.)
Coordinates
(213.7, 33.4, -365.1)
[9:16 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down — for now! (Currently paused due to no players in the event area.)
[9:16 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down — for now! (Currently paused due to no players in the event area.)
Coordinates
(213.7, 33.4, -365.1)
[9:17 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down
[9:17 AM] 
BOT
 Valheim Server Status: Event: The creatures are calming down
Coordinates
(213.7, 33.4, -365.1)

games.nwest.valheim.discordconnector.txt Removed because it had the webhook url in it
games.nwest.valheim.discordconnector-variables.txt
games.nwest.valheim.discordconnector-messages.txt
games.nwest.valheim.discordconnector-toggles.txt

latest version 1.4 no variable to toggle debug logging

The configs don't appear to have a toggle for debug logging which is filling my output with
[Debug :Valheim Discord Connector] Event check ran, no current events (or world isn't loaded yet).

Working around it with log filters but thought you may want to know.

Missing Shutdown messages - Also feature request to mute certain players (aka noisy mods)

We aren't getting the configured shutdown messages at all, and we believe this is the culprit:
HackShardGaming-WorldofValheim-ServerSideCharacters
It announces the server is being shutdown in 10 seconds (via a shout) and we would rather have neither than have that shout show up in discord.

Filtering that message and others out would be amazing, but even then we don't have shutdown messages (we also do not have startup messages, only when it's finished starting)

Hope that is helpful in some way... Looking forward to player death messages and other events =] Thanks!

Feature Request - First time event messages

A custom message for the first time a player joins
The first time a player dies
First time anything

It would be nice to see them in Discord, but also shouted in chat by the mod with a configurable name (I'm using Víðarr, Odin's son, for my webhook)

Leaderboard interval is half what it should be

I have the leaderboard interval set to 600, but it's showing every 5 hours. Seems to be due to this change in Plugin.cs:

// leaderboardTimer.Interval = 60 * 1000 * StaticConfig.StatsAnnouncementPeriod;
leaderboardTimer.Interval = 30 * 1000 * StaticConfig.StatsAnnouncementPeriod;

Not sure if that was intentional or you were just debugging.

When event starts, sends resume message

[Info: Unity Log] 11/01/2021 00:16:26: Possible events:3
[Info: Unity Log] 11/01/2021 00:16:26: Random event set:skeletons
[Debug  :Valheim Discord Connector] Trying webhook with payload: {"embeds":[{"fields":[{"name":"Coordinates","value":"(6792.6, 114.9, 1317.1)"}]}],"content":"**Event Resumed**: Skeleton surprise (Someone entered the area)"}
[Debug  :Valheim Discord Connector] Currently an event: True. Skeleton surprise | Skeletons are tired of fighting
Event: skeletons at (6792.6, 114.9, 1317.1). Status.IsRunning: True. 0.5000001 of 120 seconds completed.
PreviousEventStartMsg: , PreviousEventEndMsg: , PreviousEventPos: (0.0, 0.0, 0.0)
Involved Players: Trom Trommson
[Debug  :Valheim Discord Connector] Trying webhook with payload: {"embeds":[{"fields":[{"name":"Coordinates","value":"(6792.6, 114.9, 1317.1)"}]}],"content":"**Event**: Skeletons are tired of fighting"}
[Debug  :Valheim Discord Connector] Event stopped!

Error when checking public IP Address

Reporter wrote:

i recently have this error log from my local server hosting
where i use that map to do local testing before publish to the public hosted server
way before this it doesn't have any problem with the local server
and i can't figure what's the problem

error

They say the Discord webhook is functioning correctly though.

When shouts enabled, empty "Player Shout Message" prevents chat from working

hi, im running a modded valheim server and all global chat is blocked on the server. i tried with the vanilla chat client, and also with Chatter mod, but in each case global chat is blocked. people can use local and whisper mode chat, but global is not working. and it looks like discord connector is spitting a lot of errors into my server log.

edit: i had "Player Shout Message = " left blank, because i dont want every single shout msg sent to the server, nor the pings, but when it's blank then global chat is blocked. when i put the option back in then it works and people can shout on the server again. thats not a great option because it causes a whole lot of extra traffic from client to server that i dont want.

so, i spoke to a coder (not a skillset thats in my wheelhouse) and she told me to "Tell the mod author that":

/// <summary>
/// Sends a <paramref name="message"/> to Discord.
/// </summary>
/// <param name="message">A string optionally formatted with Discord-approved markdown syntax.</param>
public static void SendMessage(string message)
{
// A simple string message
var payload = new DiscordSimpleWebhook
{
content = message
};
string payloadString = JsonConvert.SerializeObject(payload);
SendSerializedJson(payloadString);
}

needs to be wrapped in a try-catch{} so that it doesn't stop the rest of the game code from continuing normally.

i hope that information is somewhat useful, and thx for reading this. idk if this is correct or not, but im experiencing issues disabling options in the config which im hoping you can take a look at. Log file entry below showing the error.

LogOutput for discord connector.txt

QoL/Feature Request: %player-coordinates% %ping-coordinates%

I am using ``` in a lot of my messages, but as it, coordinates display outside of the block

Would it be possible to add %player-coordinates% and %ping-coordinates% for messages?

this would allow for better message customization AND eliminate tons of config toggles for that; shortening your config quite a bit which is always nice =]

use subdir for config files

This was requested on Nexusmods:

Rofii wrote: Any chance of having the 4 .cfg files combined into 1? Or is it possible to move the 5 files into ./config/DiscordConnector/ ? Adding 5 individual files to the config folder seems overkill.

We have all the separate files to make editing not a big game of find the spot and edit. Instead you can go directly to the section you need (leaderboard, variables, toggles or main) and edit the config. It would be easy to change this to use a subdirectory but it would possibly be a breaking change!

(addendum: the records database also goes into the config dir and would be moved for this)

exception thrown on shouts and joins

After the most recent updates everything was functional, Deleted the 8-10 assemblies from the original mod and replaced with the 4 new ones. after several hours messages stopped coming in on player joins and leaves, shouts fail. exception trace below:

Oct 26 13:44:47 /supervisord: valheim-server 10/26/2021 13:44:47: Exception in ZRpc::HandlePackage: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object


Oct 26 13:44:47 /supervisord: valheim-server   at DiscordConnector.Records.Retrieve (System.String key, System.String playername) [0x00034] in <362c3a87e03241c386f3033225abd7e1>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at DiscordConnector.Patches.ChatPatches+OnNewChatMessage.Prefix (UnityEngine.GameObject& go, System.Int64& senderID, UnityEngine.Vector3& pos, Talker+Type& type, System.String& user, System.String& text) [0x002f6] in <362c3a87e03241c386f3033225abd7e1>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at (wrapper dynamic-method) Chat.DMD<Chat::OnNewChatMessage>(Chat,UnityEngine.GameObject,long,UnityEngine.Vector3,Talker/Type,string,string)


Oct 26 13:44:47 /supervisord: valheim-server   at Chat.RPC_ChatMessage (System.Int64 sender, UnityEngine.Vector3 position, System.Int32 type, System.String name, System.String text) [0x00000] in <61ccd86cd3f34ec18173f65479d19a04>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)


Oct 26 13:44:47 /supervisord: valheim-server   at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server    --- End of inner exception stack trace ---


Oct 26 13:44:47 /supervisord: valheim-server   at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00048] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x000e7] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00008] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at RoutedMethod`4[T,U,V,B].Invoke (System.Int64 rpc, ZPackage pkg) [0x0001d] in <61ccd86cd3f34ec18173f65479d19a04>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at ZRoutedRpc.HandleRoutedRPC (ZRoutedRpc+RoutedRPCData data) [0x00022] in <61ccd86cd3f34ec18173f65479d19a04>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at ZRoutedRpc.RPC_RoutedRPC (ZRpc rpc, ZPackage pkg) [0x00023] in <61ccd86cd3f34ec18173f65479d19a04>:0 


Oct 26 13:44:47 /supervisord: valheim-server   at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)


Oct 26 13:44:47 /supervisord: valheim-server   at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <eae584ce26bc40229c1b1aa476bfa589>:0 


Oct 26 13:44:47 /supervisord: valheim-server    --- End of inner exception stack trace ---

Feature Request - world save notifications

Feature Request - world save notifications
So that players know when the last time the world was saved (ie the server crashed, how much time did they lose... peace of mind... etc)

Quality of Life Suggestion - split into two CFG files

I might be an outlier here, so if you think differently I understand completely...

having gone up and down that config multiple times and it seeming longer every-time I open it, instead of separating [Notification Content Settings] and [Notification Settings], it might be easier to either combine the related configs, OR (my preference) have a second CFG file for the messages/content settings

Feature Request: Leaderboard top 5

I know you are working on updating the leaderboard, so I thought I would suggest an enhancement. We have one player that plays more than the others, so he is always at the top of the leaderboard for sessions and deaths. It would be great if instead of just the top 1 for each category, we could have a ranked list, like a top 5. I suppose you could make the number of entries to display configurable as well.

Stats Tracking/Randomized Messages

Not really an issue, more of a feature request. My friends and I were talking about how cool it would be if the bot would keep track of certain stats like how many times each of us has died or logged in and had the ability to display that in a the discord message.

We were also thinking it would be really great if you could randomize the messages. Like have a bunch of different messages for when someone logs in/out or dies.

Just some food for thought as you build this awesome bot out :) thank you for your hard work!

Support Non-Dedicated Server

I'd like to notify my friends through discord that I'm playing and they can join, but we don't use dedicated servers. I'm asking cause I downloaded it and started the game but the bepinex windows says it skipped the plugin with the reason being filtered processes "valheim_server.exe" or something like that.

From towowbc on Nexus

Duplicate Death messages being sent

After fixing the Death Position toggle, I realized now that 2 message are being sent. Also, if you have the player firsts messages enabled, you will get 3 messages.

These are all from the same death:
image

I see the issue is in the RPC_CharacterId.PostFix() method, where the if conditions need to be reworked. I can work on that, unless you would like to. Just let me know.

Tiered Least List and/or Leaderboard Sort Order

It would be awesome to also have a tiered list of the leasts for players. (tracking deaths on our server)

Currently we are just making the leader-board longer to include the leasts, but if there was a tiered list for both, we could adjust both lists to show the top 3 for each instead of displaying one longer list.

Ping Embed Visual Improvements & configurable

{embed({
"footer": {
"text": "%%Date&Time_TIMESTAMP%%"
},
"thumbnail": {
"width": 810,
"url": "%%%%%CONFIG:imageURL1a.png%%%%%",
"proxy_url": "%%%%%CONFIG:imageURL1b.png%%%%%",
"height": 810
},
"color": %%%%%CONFIG:color%%%%%,
"type": "rich",
"description": "%%%%%CONFIG:world_name%%%%%",
"fields": [
{
"value": "%%%COORDINATES_FROM_MAP%%%",
"name": "coordinates:",
"inline": false
}
]
"title": "%%PLAYER%% has pinged the map!",
"author": {
"name": "%%%%%CONFIG:server_name%%%%%",
"icon_url": "%%%%%CONFIG:imageURL2.png%%%%%"
}
})}

Leaderboards - customizable heading

How it appears currently:

Current Highest stat leader board:
Most Deaths
player_name (19)

Current leaderboard least stats:
Least Deaths
player_name (1)

Current top player leaderboard:
Top Deaths
1: player_name: 19
2: player_name: 16
3: player_name: 13
4: player_name: 5
5: player_name: 3
6: player_name: 1

We have more than one world being sent to this channel & there is no way to discern which world the leader-boards are from. It would be nice to be able to change the message preceding the lists so that we could do something like "Current Highest stat leader board in world %VAR1%:"

Also, as it currently is, leader-board is spelled one way in the highest stat, but spelled differently in the least and the top list (I'm guessing there isn't a least list at the moment?)

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.