Kheys
2 109
modifications
m (Remplacement de texte : « TableauCatégoriesFonctionnementJVC » par « TableauCatégorieFonctionnementJVC ») |
|||
| (46 versions intermédiaires par 10 utilisateurs non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
{{Bannière Info|Contenu=Cette page détaille le fonctionnement technique de jeuxvideo.com. L'API v4 du site est quant à elle documentée sur [[Documentation de l'API Jeuxvideo.com]].}} | |||
== Introduction == | == Introduction == | ||
[[Jeuxvideo.com]] utilise 2 serveurs frontaux qui sont depuis le 7 mai 2022 protégés par le service [https://cloudflare.com Cloudflare]. Chaque serveur frontal utilise un serveur HTTP Apache, tout ce qu'il y a de plus classique. En revanche, avant d'arriver sur le serveur Apache, on a plusieurs mailles dans la chaîne. En effet, lorsque vous faites une requête auprès de JVC, la chaîne suivante est effectuée avant d'arriver jusqu'au back-end : | [[Jeuxvideo.com]] utilise 2 serveurs frontaux qui sont depuis le 7 mai 2022 protégés par le service [https://cloudflare.com Cloudflare]. Chaque serveur frontal utilise un serveur HTTP Apache, tout ce qu'il y a de plus classique. En revanche, avant d'arriver sur le serveur Apache, on a plusieurs mailles dans la chaîne. En effet, lorsque vous faites une requête auprès de JVC, la chaîne suivante est effectuée avant d'arriver jusqu'au back-end : | ||
| Ligne 31 : | Ligne 33 : | ||
=== Les Cartes de visite === | === Les Cartes de visite === | ||
Les [[Carte de Visite|Cartes de visite]] étaient développés en PHP et avaient la particularité notable de stocker les données publiques de chaque utilisateur (par exemple, sa description personnelle) dans de simples fichiers HTML stockés sur disque : il n'y avait pas de requête SQL d'invoquée pour obtenir certaines données liées aux CDV. Lors de certains floods d'avis utilisateurs (notamment menés par | Les [[Carte de Visite|Cartes de visite]] étaient développés en PHP et avaient la particularité notable de stocker les données publiques de chaque utilisateur (par exemple, sa description personnelle) dans de simples fichiers HTML stockés sur disque : il n'y avait pas de requête SQL d'invoquée pour obtenir certaines données liées aux CDV. Lors de certains floods d'avis utilisateurs (notamment menés par ''UnifiedLinux''), les CDV retournaient aléatoirement des pages blanches. La cause est toujours inconnue. | ||
=== Les forums === | === Les forums === | ||
| Ligne 39 : | Ligne 41 : | ||
=== Les articles === | === Les articles === | ||
Les | Les articles n'étaient pas mis en ligne immédiatement après leur rédaction. Un système de "compilation" était nécessaire et à effectuer manuellement afin que le site "compile" les articles pour qu'ils deviennent accessibles au public. On peut imaginer que ce système de compilation a été développé dans un but de gestion de charge applicative. | ||
=== Modération === | === Modération === | ||
| Ligne 52 : | Ligne 54 : | ||
La recherche des forums était connue pour être atrocement lente et affichant incorrectement la liste des résultats, des topics étaient manquants et s'affichaient une fois sur deux. | La recherche des forums était connue pour être atrocement lente et affichant incorrectement la liste des résultats, des topics étaient manquants et s'affichaient une fois sur deux. | ||
=== Sécurité informatique === | |||
Lorsqu'une IP tentait d'envoyer trop de requêtes HTTP (HTTPS n'était pas déployé à ce moment-là), le site redirigeait chaque requête HTTP vers une erreur 404. La page d'erreur 404 étant très peu consommatrice techniquement, cela permettait de désaturer la charge serveur en cas de DoS/DDoS. | |||
Sur les CDV et les forums, il y a eu un grand nombre de failles XSS, notamment exploitées en masse par [[PyjamaSam]]. | |||
Le [[Captcha]] était également tout le temps cassé, permettant des floods de topics/messages/contributions. Cela a permis par exemple de créer un pseudo rang rubis en moins d'un jour, dont le pseudo était ''RubyOne'' (par ''UnifiedLinux'', qui a également créé un pseudo rang diamant en moins d'un jour via un flood de contributions). | |||
== Respawn == | == Respawn == | ||
| Ligne 122 : | Ligne 132 : | ||
=== Recherche des forums === | === Recherche des forums === | ||
La recherche des forums utilise le moteur de recherche Sphinx qui est intégré au site. La recherche des forums est limitée à 1 mois sur les blablas, elle peut être contournée via https://jvarchive.com/ | La recherche des forums utilise le moteur de recherche Sphinx qui est intégré au site. La recherche des forums est limitée à 1 mois sur les blablas, elle peut être contournée via https://jvarchive.com/. | ||
=== Sécurité informatique === | |||
Dans les débuts de Respawn, le site était rempli de failles permettant de faire exploser la charge du site. Il existait également de nombreuses failles sur [[ForumJV]] qui permettaient de modérer sans être modérateur, sur n'importe quel forum. Les failles ici citées ont en majorité été exploitées par [[edwado]]. | |||
Il a également existé une faille RCE (Remote Code Execution) exploitée par [[Tsain]], qui permettait d'injecter du CSS sur n'importe quelle partie du site (la faille fut très mal exploitée étant-donné que celle-ci n'était pas qu'une simple injection CSS mais bien une RCE où il était possible d'injecter un shell PHP). | |||
=== JvCare === | === JvCare === | ||
JvCare est un | JvCare est un algorithme d'obfuscation des liens externes postés sur le site. Il a été développé depuis Respawn. Il permet d'éviter la création de backlinks qui pourraient optimiser indirectement le SEO de sites externes à Jeuxvideo.com. | ||
Les codes ci-après permettent de décoder une chaîne obfusquée. | Les codes ci-après permettent de décoder une chaîne obfusquée. | ||
| Ligne 133 : | Ligne 149 : | ||
function jvCare(string $classe) : string { | function jvCare(string $classe) : string { | ||
$base16 = "0A12B34C56D78E9F"; | static $base16 = "0A12B34C56D78E9F"; | ||
$lien = ""; | $lien = ""; | ||
$s = explode(" ", $classe)[1]; | $s = explode(" ", $classe)[1]; | ||
for ($i = 0; $i < | for ($i = 0; $i < strlen($s); $i += 2) { | ||
$lien .= chr(strrpos($base16, $s[$i]) * 16 + strrpos($base16, $s[$i+1])); | $lien .= chr(strrpos($base16, $s[$i]) * 16 + strrpos($base16, $s[$i + 1])); | ||
} | } | ||
return $lien; | return $lien; | ||
| Ligne 144 : | Ligne 160 : | ||
==== JavaScript ==== | ==== JavaScript ==== | ||
function | function jvCare(classe) { | ||
const base16 = '0A12B34C56D78E9F'; | const base16 = '0A12B34C56D78E9F'; | ||
let lien = <nowiki>''</nowiki>; | let lien = <nowiki>''</nowiki>; | ||
const s = classe.split(' ')[1]; | const s = classe.split(' ')[1]; | ||
for (let i = 0; i < s.length; i += 2) { | for (let i = 0; i < s.length; i += 2) { | ||
lien += String.fromCharCode(base16.indexOf(s. | lien += String.fromCharCode(base16.indexOf(s.at(i)) * 16 + base16.indexOf(s.at(i + 1))); | ||
} | } | ||
return lien; | return lien; | ||
} | |||
===== Fonctionnel ===== | |||
function jvCake(classe) { | |||
const base16 = '0A12B34C56D78E9F'; | |||
const s = classe.split(' ')[1]; | |||
const codeUnits = s | |||
.match(/../g) | |||
.map((i) => base16.indexOf(i[0]) * 16 + base16.indexOf(i[1])); | |||
return String.fromCharCode(...codeUnits); | |||
} | } | ||
| Ligne 157 : | Ligne 184 : | ||
def jvcare(classe: str) -> str: | def jvcare(classe: str) -> str: | ||
base16 = '0A12B34C56D78E9F' | |||
s = classe.split()[1] | |||
url = <nowiki>''</nowiki> | |||
for i, j in zip(s[0::2], s[1::2]): | |||
url += chr(base16.index(i) * 16 + base16.index(j)) | |||
return url | |||
===== Liste en compréhension ===== | |||
def jvcare(classe: str) -> str: | |||
base16 = '0A12B34C56D78E9F' | |||
s = classe.split()[1] | |||
return <nowiki>''</nowiki>.join([chr(base16.index(i) * 16 + base16.index(j)) for i, j in zip(s[0::2], s[1::2])]) | |||
==== C ==== | ==== C ==== | ||
#include <stdlib.h> | |||
#include <string.h> | |||
const char *__jvcarebase16 = "0A12B34C56D78E9F"; | const char *__jvcarebase16 = "0A12B34C56D78E9F"; | ||
char *jvcare(const char *class) { | char *jvcare(const char *class) { | ||
char *s = strchr(class, ' ') + 1; | |||
int urllen = strlen(s) / 2; | |||
char *url = malloc(urllen + 1); | |||
for (int i = 0; i < urllen; i++) { | |||
char pos1 = strchr(__jvcarebase16, s[i * 2]) - __jvcarebase16; | |||
char pos2 = strchr(__jvcarebase16, s[i * 2 + 1]) - __jvcarebase16; | |||
url[i] = pos1 * 16 + pos2; | |||
} | |||
url[urllen] = '\0'; | |||
return url; | |||
} | |||
==== Awk ==== | |||
BEGIN { | |||
base16 = "0A12B34C56D78E9F" | |||
} | |||
{ | |||
s = $2 | |||
for (i = 1; i < length(s); i += 2) { | |||
pos1 = index(base16, substr(s, i, 1)) | |||
pos2 = index(base16, substr(s, i + 1, 1)) | |||
url = url sprintf("%c", (pos1 - 1) * 16 + (pos2 - 1)) | |||
} | |||
print url | |||
} | } | ||
== Phoenix == | == Phoenix == | ||
Phoenix | Phoenix était une partie de JVC développée en Node.js et utilisant React. De plus en plus abandonnée au fil du temps, elle était utilisée pour afficher la liste des jeux et des contenus de la rédaction. Phoenix utilisait une API spéciale hébergée au sous-domaine [[Documentation_de_l%27API_Jeuxvideo.com#API_jvc.gg|''api.jvc.gg'']]. Phoenix ainsi que l'API GG disparaissent en février 2025 et les pages qu'elles servaient sont basculées vers la partie principale du site <ref>https://www.jeuxvideo.com/forums/message/1297456370</ref>. | ||
== Passage en React== | |||
'''Fin mai 2025,''' jvc commence à se baser pour certaines parties du site sur la librairie [https://fr.wikipedia.org/wiki/React React] , ce qui a une grosse influence sur les [[Script|userscripts]] . | |||
Insérer du texte manuellement, ne marche plus : | |||
<s>messageTextArea.value = message;</s> | |||
Heureusement, il existe pour cela '''une fonction très utilisée''' sur le web : | |||
function fonctionreact(textarea, value) { | |||
const prototype = Object.getPrototypeOf(textarea); | |||
const nativeSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set; | |||
nativeSetter.call(textarea, value); | |||
textarea.dispatchEvent(new Event('input', { bubbles: true })); | |||
} | |||
Ensuite, il suffit simplement de faire appel à cette fonction quand on doit remplir une zone de texte : | |||
fonctionreact(messageTextArea, message); | |||
En 1er on donne la zone de texte ciblée et en 2nd le texte à insérer. | |||
Pour simplifier, <code><span style="color:red;">messageTextArea</span>.value = <span style="color:green;">message</span>;</code> devient <code>fonctionreact(<span style="color:red;">messageTextArea</span>, <span style="color:green;">message</span>);</code> avec cette fonction. | |||
=== Fonction officielle JVC === | |||
Par ailleurs, en dehors de cette méthode, JVC a proposé une entrée native pour interagir directement avec REACT :<br> | |||
<code>jvc.getMessageEditor();</code> (C'est une entrée partielle, pour réaliser des fonctions officielles du site.) | |||
https://www.jeuxvideo.com/forums/message/1286112457 | |||
jvc.getMessageEditor(".class").insertText(`mon texte`); // Place du texte à l'endroit sur le focus | |||
jvc.getMessageEditor(".class").insertStartLine(`mon texte`); // Place du texte en début de ligne. | |||
jvc.getMessageEditor(".class").selectedText; // Récupérer la sélection utilisateur. | |||
PS : Pour garantir le bon fonctionnement, utilisez simplement jvc.getMessageEditor(); '''sans le préfixe "window"'''<ref>Les userscripts sont exécutés dans un environnement isolé (appelé sandbox), ce qui empêche parfois l’accès direct aux objets définis dans le contexte global de la page, comme "window" .</ref>. <br> | |||
Il est nécessaire de faire appel à <code>jvc.getMessageEditor();</code> à chaque modification, sinon vous travaillerez avec une version antérieure de la zone de texte. | |||
Cette fonction prend directement en compte des sélecteurs CSS et pas des éléments, exemple : | |||
let selector = "#message_topic" | |||
jvc.getMessageEditor(selector).insertText('text'); //✅ Marche | |||
let selector = document.getElementById("message_topic") | |||
jvc.getMessageEditor(selector).insertText('text'); //❌ Ne marche pas | |||
Cependant, cette fonction présente plusieurs avantages notables : elle est à la fois native à JVC et intégrée au fonctionnement de React. | |||
De plus, contrairement à une modification directe du champ texte via JavaScript, cette fonction ne nécessite aucune gestion manuelle du curseur, de la sélection ou des espaces, tout est automatiquement pris en charge par la fonction elle-même. | |||
En revanche, pour manipuler le champ entièrement (suppression, remplacement) {{fleched}} la fonction a moins d'intérêt.<br> | |||
De plus, elle ne fonctionne que sur JVC, et ce n'est pas une fonction JavaScript universelle, contrairement à la précédente. | |||
== Liens externes == | == Liens externes == | ||
* [http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml Interview sur l’architecture de jeuxvideo.com de 1997 à 2005] ([http://web.archive.org/web/20070629165914/http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml archive.org]) | * [http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml Interview sur l’architecture de jeuxvideo.com de 1997 à 2005] ([http://web.archive.org/web/20070629165914/http://www.journaldunet.com/solutions/itws/050426_it_jeuxvideo.shtml archive.org]) | ||
== Voir aussi == | == Voir aussi == | ||
| Ligne 200 : | Ligne 304 : | ||
{{SectionRéférences}} | {{SectionRéférences}} | ||
{{TableauCatégorieFonctionnementJVC}} | {{TableauCatégorieFonctionnementJVC}} | ||
[[Catégorie:Fonctionnement technique de Jeuxvideo.com]] | |||
[[Catégorie:Fonctionnement de | |||
[[Catégorie:Extensions et outils]] | [[Catégorie:Extensions et outils]] | ||