Merge branch 'master' into dev

This commit is contained in:
Monty 2021-09-13 16:27:24 +02:00
commit 8d50d0b559
No known key found for this signature in database
GPG Key ID: 78B405B6520E1012
6 changed files with 130 additions and 1030 deletions

View File

@ -136,6 +136,10 @@
"title": "Our progress",
"description": "Check the project progress and goals! (Updated every hour or so, does not reflect ALL project goals or progress)"
},
"blogPage": {
"title": "Blog",
"description": "Here we have our lovely blog, which we all love so very much."
},
"localizationPage": {
"title": "Let's localize",
"description": "Paste a link to a publicly accessible JSON locale to test it on the website",

1027
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
.all-blog-posts {
max-width: 900px;
margin: 0 auto;
}
.blog-card p, .post-info {
color: var(--text-secondary);
}
.blog-card .date {
margin-bottom: 0;
font-weight: bold;
color: var(--text);
}
.blog-card iframe {
width: 100%;
aspect-ratio: 16/9;
}
.blog-card img {
max-width: 100%;
margin: 10px auto;
display: block;
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.blog-card .post-info {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.blog-card .post-info > * + * {
margin-left: .5em;
}
.blog-card .profile {
display: inline-grid;
grid-template-columns: 30px auto;
grid-gap: 10px;
font-weight: bold;
color: var(--text);
align-items: center;
}

20
src/routers/blog.js Normal file
View File

@ -0,0 +1,20 @@
const { Router } = require('express');
const util = require('../util');
const router = new Router();
router.get('/', async (request, response) => {
const reqLocale = request.locale;
const locale = util.getLocale(reqLocale.region, reqLocale.language);
const localeString = reqLocale.toString();
response.render('blog', {
layout: 'main',
locale,
localeString,
});
});
module.exports = router;

View File

@ -23,6 +23,7 @@ const routers = {
home: require('./routers/home'),
faq: require('./routers/faq'),
progress: require('./routers/progress'),
blog: require('./routers/blog'),
localization: require('./routers/localization')
};
@ -31,8 +32,7 @@ app.use(cookieParser());
// Locale express middleware setup
app.use(expressLocale({
'priority': ['cookie', 'accept-language', 'map', 'default'],
cookie: {name: 'preferredLocale'},
cookie: { name: 'preferredLocale' },
// Map unavailable regions to available locales from the same language
map: {
/* TODO: map more regions to the available locales */
@ -69,6 +69,7 @@ app.use('/', routers.home);
app.use('/faq', routers.faq);
app.use('/progress', routers.progress);
app.use('/localization', routers.localization);
app.use('/blog', routers.blog);
logger.info('Creating 404 status handler');
// This works because it is the last router created
@ -86,11 +87,11 @@ app.engine('handlebars', handlebars({
doFaq(value, options) {
let htmlLeft = '';
let htmlRight = '';
for(const [i, v] of Object.entries(value)) {
for (const [i, v] of Object.entries(value)) {
const appendHtml = options.fn({
...v
}); // Tis is an HTML string
if(i % 2 === 0) {
if (i % 2 === 0) {
htmlLeft += appendHtml;
} else {
htmlRight += appendHtml;

59
views/blog.handlebars Normal file
View File

@ -0,0 +1,59 @@
<link rel="stylesheet" href="/assets/css/blog.css" />
<div class="wrapper blog">
{{> header}}
<div class="progress-hero">
<div class="hero-meta reduced-margin">
<svg xmlns="http://www.w3.org/2000/svg" width="48.87" height="71.093" viewBox="0 0 48.87 71.093"><g id="XMLID_6_" transform="translate(0)"><path id="XMLID_15_" d="M69.581,29.593c-2.029,1.068-.249,4.129,1.78,3.061,5.162-2.67,11.463-2.6,16.981-1.1,4.735,1.282,9.5,3.845,12.246,8.045,1.246,1.922,4.307.142,3.061-1.78C96.921,27.386,80.3,24.04,69.581,29.593Z" transform="translate(-60.112 -20.086)" fill="#9d6ff3"/><path id="XMLID_14_" d="M103.359,21.045c-3.951-6.159-10.751-10-17.657-11.89C77.763,6.948,68.721,7.019,61.281,10.9c-2.029,1.068-.249,4.129,1.78,3.061,6.586-3.453,14.667-3.311,21.644-1.388,5.981,1.638,12.1,4.913,15.521,10.252C101.507,24.783,104.569,23,103.359,21.045Z" transform="translate(-54.766 -7.693)" fill="#9d6ff3"/><path id="XMLID_9_" d="M65.995,47.8a20.7,20.7,0,0,0-12.958,4.45H47.27a2.579,2.579,0,0,0-2.67,2.456v47.239a2.763,2.763,0,0,0,2.67,2.67h5.838a2.639,2.639,0,0,0,2.528-2.67V87.564A21.228,21.228,0,1,0,65.995,47.8Zm0,33.178a12,12,0,1,1,12-12A12,12,0,0,1,65.995,80.978Z" transform="translate(-44.6 -33.522)" fill="#9d6ff3"/></g></svg>
<h1 class="title dot">{{ locale.blogPage.title }}</h1>
<p class="text">{{ locale.blogPage.description }}</p>
</div>
</div>
<div class="all-blog-posts">
<div class="purple-card blog-card">
<div class="post-info">
<span>Published by</span>
<div class="profile">
<img class="profile-picture" src="https://jipfr.nl/icon.png" alt>
<span>Jip Frijlink</span>
</div>
<span>on</span>
<span class="date">1 Sept. 2021</span>
</div>
<h2>Progress report for Sept. 2021</h2>
<p>It is, but that's the point of the Patreon. Hopefully the Patreon will take off and I can make Pretendo development a full time job</p>
<p>The way game servers work on the 3DS and WiiU is through a service called NEX, which Nintendo licensed from a different company</p>
<p>NEX acts as a middleware basically. It provides a set of protocols (auth, secure connection, matchmaking, etc) and each protocol has a set of methods associated with it and each method tends to have its own dedicated custom types</p>
<img src="https://images-ext-2.discordapp.net/external/uh2DBuQss29KtEKJEmIkIUArxAhKbpmxfcTrS9dvLao/https/pbs.twimg.com/media/E_DzxqmX0AIv8Sn.jpg%3Alarge?width=526&height=702">
<p>So like every game implements AuthenticationProtocol::Login and AuthenticationProtocol::LoginEx to login with, both of which provide a AuthenticationInfo data structure</p>
<p>Every game server is made up of a mix of implemented protocols and supported methods. The trouble is that Nintendo basically hacked NEX support into their games so a lot of stuff isn't clear because NEX is a set of generic protocols and methods, and Nintendo tends to abuse them and even fork them into Nintendo-specific protocols and methods</p>
<p>For example NEX provides a protocol called DataStore, which is basically a file database with some metadata associated with the files. SMM forks DataStore into it's own DataStore(SMM) protocol, which several new (sometimes replaced) methods</p>
<p>SMM is basically 90% vanilla DataStore and DataStore(SMM), but even though Nintendo forked DataStore into their own protocol they still reuse a lot of the same generic DataStore types and data structures which leads to confusing cases of unused and weirdly used fields</p>
<iframe src="https://www.youtube.com/embed/wjWQwRlmNho" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>Like for example in DataStore(SMM) there's a method called DataStore(SMM)::RecommendedCourseSearchObject which is called to get the Course World list, and it returns a list of DataStoreCustomRankingResult data structures. Inside this data structure is 2 notable fields; MetaBinary and Ratings. MetaBinary is a NEX::Buffer type which has data like the course type, some crc32's, etc. Ratings though is the weird one. It actually doesn't store any ratings for the course, that's what the Score field does. Ratings is used to track the number of times people have attempted the course</p>
<p>But because these protocols and methods are very generic and shared between multiple games, it means knowledge of one game can't really be reused for another. Like Splatoon also implements DataStore, and also forks it into DataStore(Splatoon), and things like MetaBinary in that game are completely different</p>
<p>And then to top it all off, there are MANY versions of NEX being used by Nintendo so several games are also slightly different at the transport level (like does the server support acknowledging multiple packets at once, do the data structures have a header or not, etc). And Nintendo would update the NEX library per-game at times without documenting any version changes internally, so it's all guess work at the start as to what each game supports</p>
</div>
</div>
{{> footer }}
</div>