Compare commits

...

5 commits

Author SHA1 Message Date
60addbef43
Update README.md 2021-06-17 13:08:15 +02:00
c554f5a356
Update README.md 2021-02-08 12:47:14 +01:00
8894f3c6e0 Added support for /profile/ pages
Custom avatars now appear on `/profile/` pages. Thanks to u/ChristopherKlay on Reddit for suggesting querySelector wildcards.

Added some comments.
2021-02-08 12:01:09 +01:00
e51ee8e382
Added link to StadiaAvatar bot on Stadia
https://stadia.google.com/profile/8288375653325783432
2021-02-06 06:07:23 +01:00
d3ab9fae75 Concat of friends and messages array
Concatinating friends and messages for bulk processing.

Added empty catch() and response.status check on getStadiaAvatar() to ignore all missing avatars. (Default to Stadia avatar)

Changing HTTP Response code from 404 to 200 for missing avatars (but a userID was supplied). CORS headers are not set for error pages in NGINX. This oculd be adressed by recompiling NGINX with more_headers.
2021-02-06 05:58:54 +01:00
3 changed files with 41 additions and 17 deletions

View file

@ -1,7 +1,9 @@
<p align="center"> <p align="center">
<img width="400" src="https://www.presse-citron.net/app/uploads/2020/03/logo-stadia.png"/> <img height="52" src="https://i.imgur.com/N6UXYux.png"/>
</p>
<p align="center">
<img height="80" src="https://i.imgur.com/ZxZKGhp.png"/>
</p> </p>
<h1 align="center">Stadia Avatar</h1>
<h3 align="center">Use Gravatars with Google Stadia.</h2> <h3 align="center">Use Gravatars with Google Stadia.</h2>
<p align="center">Userscript for <a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo">Tampermonkey</a> to bring <a href="http://en.gravatar.com/">Globally Recognized Avatars (Gravatars)</a> into Stadia for you and your friends.</p> <p align="center">Userscript for <a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo">Tampermonkey</a> to bring <a href="http://en.gravatar.com/">Globally Recognized Avatars (Gravatars)</a> into Stadia for you and your friends.</p>
<p align="center"> <p align="center">
@ -9,6 +11,11 @@
</p> </p>
<p align="center"><i><strong>Stadia Avatar is not affiliated with Stadia or Google LLC.</strong><br>Stadia, the Stadia beacon, and related marks and logos are trademarks of Google LLC.</i></p> <p align="center"><i><strong>Stadia Avatar is not affiliated with Stadia or Google LLC.</strong><br>Stadia, the Stadia beacon, and related marks and logos are trademarks of Google LLC.</i></p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/VictorWesterlund/stadia-avatar"/>
<img alt="API Status" src="https://img.shields.io/endpoint?url=https://api.victorwesterlund.com/status?api=stadia-avatar"/>
<img alt="Maintenance" src="https://img.shields.io/maintenance/no/2021"/>
</p>
<h2>Installing / Get started</h2> <h2>Installing / Get started</h2>
<p><strong>Disclaimer before we get started!</strong><br>Stadia Avatar relies on a third-party database to store and retrieve the Gravatars. Your Stadia player ID and Gravatar hash is stored and made available to the public through Stadia Avatar's API.</p> <p><strong>Disclaimer before we get started!</strong><br>Stadia Avatar relies on a third-party database to store and retrieve the Gravatars. Your Stadia player ID and Gravatar hash is stored and made available to the public through Stadia Avatar's API.</p>
<p>Information stored is and will always be limited to <strong>player ID</strong>, <strong>Gravatar hash</strong> and a <strong>Last-modified timestamp</strong>.</p> <p>Information stored is and will always be limited to <strong>player ID</strong>, <strong>Gravatar hash</strong> and a <strong>Last-modified timestamp</strong>.</p>
@ -18,17 +25,12 @@
<li><p>Head over to <a href="https://greasyfork.org/en/scripts/421251-stadia-avatars">GreasyFork and install the Stadia Avatar client Userscipt</a>.</p> <li><p>Head over to <a href="https://greasyfork.org/en/scripts/421251-stadia-avatars">GreasyFork and install the Stadia Avatar client Userscipt</a>.</p>
<li><p>Wait for the Userscript to install, and then open <a href="http://stadia.com/">Stadia</a>. <i>(Stadia Avatar is now installed.)</i></p> <li><p>Wait for the Userscript to install, and then open <a href="http://stadia.com/">Stadia</a>. <i>(Stadia Avatar is now installed.)</i></p>
<li><p>To link your <a href="#creating-a-gravatar-account--changing-your-profile-picture">Gravatar account</a> with Stadia, head over to the Messages tab in your friends list.</p> <li><p>To link your <a href="#creating-a-gravatar-account--changing-your-profile-picture">Gravatar account</a> with Stadia, head over to the Messages tab in your friends list.</p>
<li><p>Send a message to <strong>StadiaAvatar#8777</strong> (Stadia Avatar bot) with the e-mail associated to your Gravatar account.</p><p><strong>Sign up to Gravatar with a disposable E-mail <i>(such as <a href="https://10minutemail.com/">10minutemail.com</a>)</i> if you wish to keep your actual E-mail private.</strong></p> <li><p>Send a message to <a href="https://stadia.google.com/profile/8288375653325783432"><strong>StadiaAvatar#8777</strong></a> (Stadia Avatar bot) with the e-mail associated to your Gravatar account.</p><p><strong>Sign up to Gravatar with a disposable E-mail <i>(such as <a href="https://10minutemail.com/">10minutemail.com</a>)</i> if you wish to keep your actual E-mail private.</strong></p>
<li><p><i>That's it!</i> Refresh the page now to see your Gravatar.</p> <li><p><i>That's it!</i> Refresh the page now to see your Gravatar.</p>
<p><i>The bot will not respond to your message. Make sure you entered your E-mail correctly if you see the default Gravatar picture. If nothing changed at all, the bot is most likely not working :)</i></p> <p><i>The bot will not respond to your message. Make sure you entered your E-mail correctly if you see the default Gravatar picture. If nothing changed at all, the bot is most likely not working :)</i></p>
</ol> </ol>
<h3>Creating a Gravatar account / Changing your profile picture</h3> <h3>Creating a Gravatar account / Changing your profile picture</h3>
<p>Follow the instruction on <a href="http://en.gravatar.com/">gravatar.com</a> to set up your Gravatar account.</p> <p>Follow the instruction on <a href="http://en.gravatar.com/">gravatar.com</a> to set up your Gravatar account.</p>
<h2>Known issues!</h2>
<table>
<tr><th colspan=2>Issue</th></tr>
</tr><td><strong>Avatars don't work on profile pages</strong></td><td>Original Stadia profile pictures are shown on all <code>/profile/</code> pages.<br>Ambiguity in the DOM makes it difficult to link a profile page to a specific user.</td></tr>
</table>
<h2>Report issues & suggest features</h2> <h2>Report issues & suggest features</h2>
<p>Please report bugs and suggest new features under <a href="https://github.com/VictorWesterlund/stadia-avatar/issues">Issues</a>.</p> <p>Please report bugs and suggest new features under <a href="https://github.com/VictorWesterlund/stadia-avatar/issues">Issues</a>.</p>
<h2>License</h2> <h2>License</h2>

View file

@ -9,7 +9,7 @@
$avatar = $db->get_avatar($user_id); $avatar = $db->get_avatar($user_id);
if(!$avatar) { if(!$avatar) {
error("404","No avatar was found for the supplied userID"); error("200","No avatar was found for the supplied userID");
} }
echo "{\"status\":\"OK\",\"avatar\":\"${avatar}\"}"; echo "{\"status\":\"OK\",\"avatar\":\"${avatar}\"}";

View file

@ -43,14 +43,26 @@
// Serialized group of selectors based on context // Serialized group of selectors based on context
selectors(group,id = false) { selectors(group,id = false) {
switch(group) { switch(group) {
case "me": return ".ksZYgc, .rybUIf"; case "me": return `
case "friends": return `.Y1rZWd[data-playerid="${id}"] .Fnd1Pd, .w2Sl7c[data-playerid="${id}"] .drvCDc`; c-wiz[data-p*="${id}"] .XZRzG,
.OGtUWe .dOyvbe,
.ksZYgc,
.rybUIf
`;
case "friends": return `
div[jsdata*="${id}"] .PwtJse,
c-wiz[data-p*="${id}"] .XZRzG,
c-wiz[data-p*="${id}"] .drvCDc,
c-wiz[data-p*="${id}"] .vLPc0c,
.Y1rZWd[data-player-id="${id}"] .Fnd1Pd,
.Y1rZWd[data-playerid="${id}"] .Fnd1Pd,
.w2Sl7c[data-playerid="${id}"] .drvCDc
`;
} }
} }
add(selectors,avatar) { add(selectors,avatar) {
this.sheet.insertRule(`${selectors} { background-image: url(${avatar}) !important; }`); this.sheet.insertRule(`${selectors} { background-image: url(${avatar}) !important; }`);
console.log(`${selectors} { background-image: url(${avatar}) !important; }`);
} }
} }
@ -65,6 +77,7 @@
return id; return id;
} }
// Fetch Gravatar hash from endpoint
async function getStadiaAvatar(playerID) { async function getStadiaAvatar(playerID) {
stadiaAvatar.searchParams.set("userID",playerID); stadiaAvatar.searchParams.set("userID",playerID);
@ -75,14 +88,20 @@
// Fetch avatar and append to stylesheet // Fetch avatar and append to stylesheet
function replaceWithGravatar(group,playerID) { function replaceWithGravatar(group,playerID) {
getStadiaAvatar(playerID).then(response => { getStadiaAvatar(playerID).then(response => {
if(response.status !== "OK") {
return false;
}
gravatar.pathname = "/avatar/" + response.avatar; // Append Gravatar hash gravatar.pathname = "/avatar/" + response.avatar; // Append Gravatar hash
avatars.add(avatars.selectors(group,playerID),gravatar); // Add style override by group avatars.add(avatars.selectors(group,playerID),gravatar); // Add style override by group
}); }).catch(
// Ignore missing avatars
);
} }
// ---- // ----
replaceWithGravatar("me",getID(document.querySelector("[jsname='HiaYvf']"))); replaceWithGravatar("me",getID(document.querySelector("[jsname='HiaYvf']"))); // Append styles for my avatar
function updateFamily(group,wrapper) { function updateFamily(group,wrapper) {
for(const element of wrapper) { for(const element of wrapper) {
@ -97,14 +116,17 @@
let timeout = null; let timeout = null;
// Fetch friend avatars
const friendsList = (mutation,observer) => { const friendsList = (mutation,observer) => {
clearTimeout(timeout); clearTimeout(timeout);
// Wait until subtree stops mutating (on initial load)
timeout = setTimeout(() => { timeout = setTimeout(() => {
const friends = document.querySelector("[jsname='FhFdCc']").children; let elements = [];
const messages = document.querySelector("[jsname='FhFdCc']").children; elements = Array.prototype.concat.apply(elements,document.querySelector("[jsaction='JIbuQc:mbLu7b']").children); // Friends list
elements = Array.prototype.concat.apply(elements,document.querySelector("[jsname='FhFdCc']").children); // Messages list
updateFamily("friends",messages); updateFamily("friends",elements);
},700); },700);
} }