Venir d'un autre téléphone
Une ville possédant déjà un téléphone accumule des années de données : des numéros appris par cœur, des conversations, des photos, des @handles. Tout perdre est le véritable coût d’un changement de téléphone, et c’est la raison pour laquelle la plupart des serveurs ne sautent jamais le pas. Cette fonctionnalité lit les tables de l’ancien téléphone et remplit les nôtres.
Quatre téléphones sont pris en charge, et tous les quatre sont testés selon la même procédure : leurs tables sont créées à partir du schéma fourni par leur installateur, une petite ville y est injectée, l’importation est exécutée en conditions réelles, puis chaque ligne revendiquée est ensuite vérifiée.
| Origine | Ses tables | Ce sur quoi tout est indexé |
|---|---|---|
| lb-phone | phone_* | le numéro de téléphone, avec phone_phones reliant le numéro à un propriétaire |
| Quasar Smartphone Pro | qs_phone_* | un scope_id — un téléphone physique, et non un joueur |
| NPWD | npwd_* | l’identifiant du framework, et ses numéros sont déjà dans users |
| qb-phone | player_contacts, phone_messages… | citizenid, qui correspond au propriétaire de ce téléphone sur QBCore |
Trois garanties
Section intitulée « Trois garanties »L’ancien téléphone n’est jamais modifié. Pas une seule requête n’écrit dans une table qui n’est pas la nôtre. Les données de lb-phone restent strictement intactes, ce qui rend le retour en arrière immédiat : supprimez simplement nos lignes.
La répétition générale est réelle. DryRun est activé par défaut. Il lit tout ce qu’une exécution réelle lit, détermine chaque ligne qu’il écrirait, n’en écrit aucune et affiche le décompte. C’est exactement le même code — une simulation qui prendrait des raccourcis ne simulerait rien de valable.
L’import ne peut pas s’exécuter deux fois. Une exécution réelle laisse un reçu dans la base de données. Le démarrage suivant le détecte et s’arrête, évitant ainsi qu’une ligne de configuration oubliée ne vienne dupliquer chaque conversation de la ville.
Procédure
Section intitulée « Procédure »-- shared/config/import.luaConfig.Import = { From = 'lb-phone', -- or false, which is where it starts DryRun = true, -- read the count first Numbers = 'keep', -- their old numbers move across Crypto = 'cash', -- sell their coins at their own price}Redémarrez une fois et lisez la console :
[mic_phone import] lb-phone — REHEARSAL, nothing was written[mic_phone import] contacts 482[mic_phone import] messages 19104[mic_phone import] numbers 137[mic_phone import] photos 2210[mic_phone import] social 96[mic_phone import] · a phone whose owner is not in `users` any more was skipped (×8)[mic_phone import] · lb-phone does not say whether an alarm repeats, so its alarms arrive as one-off alarmsPuis passez à DryRun = false, redémarrez une dernière fois, et remettez From = false une fois l’opération terminée.
Si les tables sont absentes de cette base de données, le script le signale et ne fait rien ; indiquer le mauvais téléphone ne vous coûte qu’une ligne dans la console.
Ce qui est transféré
Section intitulée « Ce qui est transféré »Tout ce qui suit concerne lb-phone, qui est le plus complet des quatre. Les spécificités des trois autres sont détaillées plus bas.
| Depuis lb-phone | Devient |
|---|---|
phone_phones | le numéro dans users, la batterie, les paramètres du téléphone |
ses settings.apps | l’écran d’accueil — le même dock, les mêmes applications sur les mêmes pages |
phone_phone_contacts | les contacts, avec favoris et photos |
phone_message_* | les conversations, les groupes et les compteurs de messages non lus |
phone_phone_calls | l’historique d’appels, une ligne par côté, appels manqués inclus |
phone_photos | la bibliothèque, photos et vidéos |
phone_mail_* | les e-mails, lus et non lus |
phone_maps_locations | les lieux enregistrés |
phone_marketplace_posts, phone_yellow_pages_posts | les annonces |
| Instagram, Twitter, TikTok, Tinder | Instapic, Twixel, Klipz, Flinder — identifiants, noms, photos, biographies, posts, abonnements et badge certifié |
phone_darkchat_* | le darknet : le salon, qui y était présent, ce qui a été dit |
phone_notes, phone_clock_alarms | notes et alarmes — les alarmes de lb-phone ne précisant pas si elles se répètent, elles arrivent sous forme d’alarmes uniques |
phone_crypto | voir Crypto ci-dessous |
Les images sont des URL sur les deux téléphones, donc rien n’est téléchargé ni téléversé à nouveau. Les photos d’un joueur continuent de fonctionner dès le premier jour parce qu’elles n’ont jamais appartenu à l’un ou l’autre téléphone au départ.
Ce qui ne l’est pas, et pourquoi
Section intitulée « Ce qui ne l’est pas, et pourquoi »Le rapport d’importation détaille chacun de ces points explicitement plutôt que de laisser planer un doute.
- Fonds d’écran et sonneries. Les leurs nomment leurs propres fichiers, les nôtres nomment les nôtres. Une image incorrecte est pire que celle par défaut.
- Mots de passe des réseaux sociaux. Voir ci-dessous — les comptes sont importés, les mots de passe ne le peuvent pas.
- Mode avion, volontairement. Importer un commutateur laissé activé reviendrait à importer un téléphone inopérant et un joueur incapable de comprendre pourquoi.
- Albums photos. Chaque image figure dans la bibliothèque générale ; les albums ne sont pas reconstruits.
Les trois autres, et leurs spécificités
Section intitulée « Les trois autres, et leurs spécificités »Quasar Smartphone Pro
Section intitulée « Quasar Smartphone Pro »Le mieux conçu des quatre, dont le mapping est exact plutôt qu’approximatif sur trois points :
- Les compteurs de non-lus sont recalculés, pas copiés. Quasar enregistre
last_read_message_id; nous enregistrons un total. Ce total est donc calculé — combien de messages dans cette conversation sont arrivés après le dernier message lu — ce qui reste exact même si leur propre compteur s’était déréglé. - L’historique des appels indique déjà
incoming,outgoingetmissed, qui correspondent exactement à nos trois statuts. - Une photo sait si elle est une vidéo, avec sa durée et sa vignette d’illustration, de sorte qu’elle arrive comme telle.
Les notes (les notes épinglées restent épinglées), alarmes, entrées de calendrier et rappels sont également importés : un rappel ouvert avec une date d’échéance devient un événement de calendrier, un rappel sans date conserve son texte sous forme de note, et un rappel terminé est laissé de côté. Quasar pouvant répéter une alarme uniquement le week-end, ce que ce téléphone ne fait pas, ces dernières arrivent sous forme d’alarmes uniques.
Les conversations épinglées et mises en sourdine conservent ces deux propriétés. Les e-mails arrivent avec le dossier dans lequel ils se trouvaient — les brouillons et la corbeille sont ignorés, car un brouillon jamais envoyé ne mérite pas d’être déplacé. Ce qui n’est pas importé : leurs paramètres et l’écran d’accueil, stockés dans un objet JSON propre à Quasar, ainsi que leurs identifiants d’App Store, qui diffèrent des nôtres.
À savoir : Quasar autorise un personnage à détenir plusieurs téléphones, alors que celui-ci conserve un numéro par personnage. Le premier numéro traité lui revient ; tout autre numéro est répertorié dans le rapport et rien n’est écrasé.
Le plus simple, pour une raison qu’il convient de souligner : NPWD conserve déjà le numéro dans users.phone_number, qui est précisément la colonne que lit ce téléphone. Sur un serveur NPWD par défaut, il n’y a rien à migrer, et le rapport le confirme plutôt que de simuler un transfert.
Ses conversations sont nommées par une chaîne de caractères contenant les numéros associés plutôt que par un ID, la liaison s’effectue donc sur cette chaîne. Son nom de profil Twitter devient le @handle ; Match ne comportant aucun nom d’utilisateur, un compte Flinder est indexé sur le numéro du personnage. Les photos n’ayant pas de date propre, la bibliothèque est ordonnée chronologiquement selon l’ordre des prises de vue. Les notes sont importées sur le même principe, datées selon l’ordre de rédaction. Les annonces ne comportant aucun prix, elles arrivent à zéro.
qb-phone
Section intitulée « qb-phone »Le plus ancien, et celui qui ressemble le moins au nôtre — mais l’identité est immédiate, car sur QBCore ce téléphone exploite déjà le citizenid qui sert d’index à l’ensemble de qb-phone.
Ses conversations représentent l’essentiel du travail. qb-phone n’a pas de concept de conversation centralisée : phone_messages correspond à une ligne par personne et par numéro avec l’ensemble des échanges au format JSON, renseigné séparément de chaque côté. La même conversation existe donc en double et les deux copies ne concordent pas forcément. Chaque paire de numéros est par conséquent reconstruite une seule fois, à partir du côté le plus complet — les fusionner inventerait un faux ordre chronologique, et importer les deux donnerait chaque message en double à tout le monde. Une conversation sans horodatage conserve son ordre d’apparition et se voit espacée d’une minute par message.
Les numéros résident dans players.charinfo au format JSON plutôt que dans une colonne dédiée ; ils sont donc extraits de là pour être écrits là où ce téléphone les gère. Les tweets comportent un nom plutôt qu’un compte, si bien qu’un compte Twixel est créé par personnage à partir de son nom.
Numbers = 'keep' constitue la raison d’être de toute cette démarche : le numéro inscrit sur la carte de visite d’un joueur, et enregistré dans les répertoires des autres, continue de le joindre.
Un numéro n’est jamais inscrit que dans une colonne vide. Si un personnage en possède déjà un ici et qu’il est différent, il s’agit d’un conflit : il est comptabilisé, consigné dans le rapport, et rien n’est écrasé. Leurs anciens numéros conservent en outre leur ancien format — 1234567890 plutôt que le format 555-###-#### de ce téléphone —, ce qui est purement cosmétique et ne concerne que les numéros attribués par la suite.
Numbers = 'ours' les laisse intacts et charge ce téléphone d’en attribuer de nouveaux. Leurs anciens contacts ne mèneront à personne ; cette option ne s’adresse donc qu’à une ville repartant de zéro.
Comptes de réseaux sociaux
Section intitulée « Comptes de réseaux sociaux »Leurs mots de passe sont stockés en clair dans une colonne. Les nôtres sont un hash PBKDF2 généré dans le navigateur du joueur, et l’un ne peut pas être déduit de l’autre — le mot de passe est donc le seul élément qui ne franchit pas l’importation, et il n’est stocké nulle part en cours de route.
Le compte arrive avec le statut importé. La première fois que son propriétaire ouvre l’application, le téléphone indique Ce compte provient de votre ancien téléphone. Choisissez un mot de passe pour celui-ci, et celui-ci devient le mot de passe effectif.
Ce procédé est plus sûr que ne le serait un mot de passe : la ligne désigne un propriétaire, et le serveur sait qui effectue la demande sans qu’on ait à le lui déclarer. Rien ne serait prouvé par un mot de passe qui n’a jamais été géré par notre ressource.
Il n’existe aucun taux de change légitime entre deux marchés fictifs, décidez donc de la règle plutôt que de la laisser au hasard :
'cash'— vendre au cours de l’ancien téléphone et l’inscrire dans le portefeuille comme un virement. Personne ne gagne, personne ne perd, et aucun accord n’a besoin d’être trouvé.'skip'— ne rien faire. Leurs avoirs restent dans leurs tables d’origine et peuvent être gérés manuellement.- une table — votre propre correspondance personnalisée, si les avoirs doivent subsister sous forme de monnaies :
Crypto = { qbit = 'santo', lifeinvader = 'vine' },En cas de problème
Section intitulée « En cas de problème »Rien de ce qui appartenait à l’ancien téléphone n’a été touché, par conséquent :
- Supprimez nos lignes pour l’étape ayant posé problème — le rapport les liste.
- Supprimez le reçu :
DELETE FROM mic_phone_json WHERE owner = '@import'. - Passez
Config.Import.Again = true, et relancez l’opération.
Skip permet d’exclure certaines étapes spécifiques d’après les noms affichés par le rapport :
Skip = { 'photos', 'crypto' },