1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-03-14 02:16:10 +00:00

Add hash40, ability to name plugin

This commit is contained in:
jam1garner 2020-04-09 21:54:01 -04:00
parent 11cc29058e
commit 476fb8788f
13 changed files with 287 additions and 42 deletions

17
Cargo.lock generated
View file

@ -1,5 +1,20 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -42,6 +57,7 @@ dependencies = [
name = "skyline"
version = "0.0.1"
dependencies = [
"crc",
"nnsdk",
"skyline_libc",
"skyline_macro",
@ -55,6 +71,7 @@ version = "0.1.0"
name = "skyline_macro"
version = "0.1.0"
dependencies = [
"crc",
"lazy_static",
"proc-macro2",
"quote",

17
skyline/Cargo.lock generated
View file

@ -1,5 +1,18 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -32,6 +45,7 @@ dependencies = [
name = "skyline"
version = "0.0.1"
dependencies = [
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nnsdk 0.1.0",
"skyline_libc 0.1.0",
"skyline_macro 0.1.0",
@ -45,6 +59,7 @@ version = "0.1.0"
name = "skyline_macro"
version = "0.1.0"
dependencies = [
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -67,6 +82,8 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"

View file

@ -10,3 +10,4 @@ edition = "2018"
skyline_macro = { path = "./skyline_macro" }
nnsdk = { path = "./nnsdk" }
skyline_libc = { path = "./skyline_libc" }
crc = { version = "1.8", default-features = false }

View file

@ -1596,7 +1596,7 @@ pub mod root {
);
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2os21TimedPeekMessageQueueEPmPKNS0_16MessageQueueTypeENS_8TimeSpanE"]
#[link_name = "\u{1}_ZN2nn2os21TimedPeekMessageQueueEPmPKNS0_16MessageQueueTypeE"]
pub fn TimedPeekMessageQueue(
arg1: *mut u64,
arg2: *const root::nn::os::MessageQueueType,
@ -1638,7 +1638,7 @@ pub mod root {
pub fn BroadcastConditionVariable(arg1: *mut root::nn::os::ConditionVariableType);
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2os21WaitConditionVariableEPNS0_21ConditionVariableTypeEPNS0_9MutexTypeE"]
#[link_name = "\u{1}_ZN2nn2os21WaitConditionVariableEPNS0_21ConditionVariableTypeE"]
pub fn WaitConditionVariable(arg1: *mut root::nn::os::ConditionVariableType);
}
extern "C" {
@ -2394,7 +2394,7 @@ pub mod root {
pub fn Initialize();
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2oe27SetPerformanceConfigurationENS0_15PerformanceModeEi"]
#[link_name = "\u{1}_ZN2nn2oe27SetPerformanceConfigurationEii"]
pub fn SetPerformanceConfiguration(
arg1: root::nn::oe::PerformanceMode,
arg2: root::s32,
@ -2421,7 +2421,7 @@ pub mod root {
pub fn SetPerformanceModeChangedNotificationEnabled(arg1: bool);
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2oe20SetFocusHandlingModeENS0_17FocusHandlingModeE"]
#[link_name = "\u{1}_ZN2nn2oe20SetFocusHandlingModeEi"]
pub fn SetFocusHandlingMode(arg1: root::nn::oe::FocusHandlingMode);
}
extern "C" {
@ -2521,6 +2521,19 @@ pub mod root {
#[link_name = "\u{1}_ZN2nn7account10InitializeEv"]
pub fn Initialize();
}
extern "C" {
#[link_name = "\u{1}_ZN2nn7account15ShowUserCreatorEv"]
pub fn ShowUserCreator();
}
pub mod detail {
extern "C" {
#[link_name = "\u{1}_ZN2nn7account6detail13IsInitializedEv"]
pub fn IsInitialized() -> bool;
}
}
extern "C" {
#[link_name = "\u{1}_ZN2nn7account12ListAllUsersEPiPNS0_3UidEi"]
pub fn ListAllUsers(
@ -2625,7 +2638,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn7account12AsyncContextC2Ev"]
#[link_name = "\u{1}_ZN2nn7account12AsyncContextC1Ev"]
pub fn AsyncContext_AsyncContext(this: *mut root::nn::account::AsyncContext);
}
impl AsyncContext {
@ -2849,7 +2862,7 @@ pub mod root {
pub fn QueryMountRomCacheSize(size: *mut u64) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2fs22QueryMountRomCacheSizeEPmi"]
#[link_name = "\u{1}_ZN2nn2fs22QueryMountRomCacheSizeEPmm"]
pub fn QueryMountRomCacheSize1(
size: *mut u64,
arg1: root::nn::ApplicationId,
@ -2868,7 +2881,7 @@ pub mod root {
pub fn CanMountRomForDebug() -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2fs11CanMountRomENS_13ApplicationIdE"]
#[link_name = "\u{1}_ZN2nn2fs11CanMountRomEm"]
pub fn CanMountRom(arg1: root::nn::ApplicationId) -> root::Result;
}
extern "C" {
@ -2892,7 +2905,7 @@ pub mod root {
pub fn EnsureSaveData(arg1: *const root::nn::account::Uid) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2fs13MountSaveDataEPKcNS_13ApplicationIdERKNS_7account3UidE"]
#[link_name = "\u{1}_ZN2nn2fs13MountSaveDataEPKcm"]
pub fn MountSaveData(
arg1: *const skyline_libc::c_char,
arg2: root::nn::fs::UserId,
@ -2940,7 +2953,7 @@ pub mod root {
pub fn DeleteFile(filepath: *const skyline_libc::c_char) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2fs8ReadFileEPmNS0_10FileHandleElPvm"]
#[link_name = "\u{1}_ZN2nn2fs8ReadFileEPmNS0_10FileHandleElPvmRKi"]
pub fn ReadFile(
outSize: *mut u64,
handle: root::nn::fs::FileHandle,
@ -3778,7 +3791,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2ro20UnregisterModuleInfoEPNS0_16RegistrationInfoE"]
#[link_name = "\u{1}_ZN2nn2ro20UnregisterModuleInfoEPNS0_16RegistrationInfoEPKv"]
pub fn UnregisterModuleInfo(
arg1: *mut root::nn::ro::RegistrationInfo,
arg2: *const skyline_libc::c_void,
@ -4561,7 +4574,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn5prepo10PlayReport9SetBufferEPvm"]
#[link_name = "\u{1}_ZN2nn5prepo10PlayReport9SetBufferEv"]
pub fn PlayReport_SetBuffer(this: *mut root::nn::prepo::PlayReport)
-> root::Result;
}
@ -4601,7 +4614,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn5prepo10PlayReportC1EPKc"]
#[link_name = "\u{1}_ZN2nn5prepo10PlayReportC1Ev"]
pub fn PlayReport_PlayReport(this: *mut root::nn::prepo::PlayReport);
}
impl PlayReport {
@ -4689,7 +4702,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn2vi11CreateLayerEPPNS0_5LayerEPNS0_7DisplayENS_4util10BitFlagSetILi32ENS0_15CompositorFlagsEEE"]
#[link_name = "\u{1}_ZN2nn2vi11CreateLayerEPNS0_5LayerEPNS0_7DisplayE"]
pub fn CreateLayer(
out_Layer: *mut root::nn::vi::Layer,
disp: *mut root::nn::vi::Display,
@ -4899,7 +4912,7 @@ pub mod root {
) -> root::s64;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn5image11JpegDecoder6DecodeEPvmiS2_m"]
#[link_name = "\u{1}_ZN2nn5image11JpegDecoder6DecodeEPvliS2_l"]
pub fn JpegDecoder_Decode(
this: *mut root::nn::image::JpegDecoder,
out: *mut skyline_libc::c_void,
@ -4910,7 +4923,7 @@ pub mod root {
) -> root::nn::image::JpegStatus;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn5image11JpegDecoderC2Ev"]
#[link_name = "\u{1}_ZN2nn5image11JpegDecoderC1Ev"]
pub fn JpegDecoder_JpegDecoder(this: *mut root::nn::image::JpegDecoder);
}
impl JpegDecoder {
@ -4953,7 +4966,7 @@ pub mod root {
}
}
extern "C" {
#[link_name = "\u{1}_ZN2nn5image11JpegDecoderD0Ev"]
#[link_name = "\u{1}_ZN2nn5image11JpegDecoderD1Ev"]
pub fn JpegDecoder_JpegDecoder_destructor(this: *mut root::nn::image::JpegDecoder);
}
}
@ -4966,7 +4979,7 @@ pub mod root {
pub fn Initialize();
}
extern "C" {
#[link_name = "\u{1}_ZN2nn7friends14GetProfileListEPNS0_12AsyncContextEPNS0_7ProfileEPKNS_7account23NetworkServiceAccountIdEi"]
#[link_name = "\u{1}_ZN2nn7friends14GetProfileListEPNS0_12AsyncContextEPNS0_7ProfileERKNS_7account3UidEPKmi"]
pub fn GetProfileList(
context: *mut root::nn::friends::AsyncContext,
profiles: *mut root::nn::friends::Profile,
@ -5010,7 +5023,7 @@ pub mod root {
pub fn Profile_IsValid(this: *const root::nn::friends::Profile) -> bool;
}
extern "C" {
#[link_name = "\u{1}_ZNK2nn7friends7Profile18GetProfileImageUrlEPNS0_3UrlENS0_9ImageSizeE"]
#[link_name = "\u{1}_ZN2nn7friends7Profile18GetProfileImageUrlEPA160_ci"]
pub fn Profile_GetProfileImageUrl(
this: *mut root::nn::friends::Profile,
arg1: *mut root::nn::friends::Url,
@ -5081,7 +5094,7 @@ pub mod root {
) -> root::Result;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn7friends12AsyncContextC2Ev"]
#[link_name = "\u{1}_ZN2nn7friends12AsyncContextC1Ev"]
pub fn AsyncContext_AsyncContext(this: *mut root::nn::friends::AsyncContext);
}
extern "C" {
@ -5194,7 +5207,7 @@ pub mod root {
);
}
extern "C" {
#[link_name = "\u{1}_ZN2nn4diag6detail9AbortImplEPKcS3_S3_i"]
#[link_name = "\u{1}_ZN2nn4diag6detail9AbortImplEPKcS3_S3_ij"]
pub fn AbortImpl1(
arg1: *const skyline_libc::c_char,
arg2: *const skyline_libc::c_char,
@ -5412,11 +5425,11 @@ pub mod root {
);
}
extern "C" {
#[link_name = "\u{1}_ZNK2nn3mem17StandardAllocator4DumpEv"]
#[link_name = "\u{1}_ZN2nn3mem17StandardAllocator4DumpEv"]
pub fn StandardAllocator_Dump(this: *mut root::nn::mem::StandardAllocator);
}
extern "C" {
#[link_name = "\u{1}_ZN2nn3mem17StandardAllocatorC2EPvmb"]
#[link_name = "\u{1}_ZN2nn3mem17StandardAllocatorC1Ev"]
pub fn StandardAllocator_StandardAllocator(
this: *mut root::nn::mem::StandardAllocator,
);
@ -6522,7 +6535,7 @@ pub mod root {
pub fn IsNetworkRequestOnHold() -> bool;
}
extern "C" {
#[link_name = "\u{1}_ZN2nn4nifm26GetCurrentPrimaryIpAddressEP7in_addr"]
#[link_name = "\u{1}_ZN2nn4nifm26GetCurrentPrimaryIpAddressEPm"]
pub fn GetCurrentPrimaryIpAddress(inAddr: *mut u64) -> root::Result;
}
}

View file

@ -1,5 +1,20 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -28,6 +43,7 @@ dependencies = [
name = "skyline_macro"
version = "0.1.0"
dependencies = [
"crc",
"lazy_static",
"proc-macro2",
"quote",

View file

@ -14,3 +14,4 @@ syn = { version = "1", features = ["full", "extra-traits"] }
quote = "1"
proc-macro2 = "1"
lazy_static = "1.4"
crc = { version = "1.8", default-features = false }

View file

@ -0,0 +1,36 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
pub struct Attrs {
name: String,
}
impl Parse for Attrs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let meta: syn::MetaNameValue = input.parse()?;
if meta.path.get_ident().unwrap().to_string() == "name" {
match meta.lit {
syn::Lit::Str(string) => {
Ok(Attrs {
name: string.value()
})
}
_ => panic!("Invalid literal, must be a string")
}
} else {
panic!("Attributes other than 'name' not allowed");
}
}
}
impl ToTokens for Attrs {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let name = &self.name[..];
quote::quote!(
::skyline::set_module_name!(#name);
).to_tokens(tokens);
}
}

View file

@ -1,8 +1,9 @@
use quote::{ToTokens, quote};
use proc_macro::TokenStream;
use syn::{parse_macro_input, token, Ident, AttrStyle};
use syn::{parse_macro_input, token, Ident, AttrStyle, Lit, spanned::Spanned};
use proc_macro2::{Span, TokenStream as TokenStream2};
mod attributes;
fn new_attr(attr_name: &str) -> syn::Attribute {
syn::Attribute {
@ -15,9 +16,11 @@ fn new_attr(attr_name: &str) -> syn::Attribute {
}
#[proc_macro_attribute]
pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
pub fn main(attrs: TokenStream, item: TokenStream) -> TokenStream {
let mut main_function = parse_macro_input!(item as syn::ItemFn);
let attr_code = parse_macro_input!(attrs as attributes::Attrs);
main_function.attrs.push(
new_attr("no_mangle")
);
@ -27,6 +30,7 @@ pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
let mut output = TokenStream2::new();
quote!(
#attr_code
use skyline::prelude::*;
::skyline::setup!();
).to_tokens(&mut output);
@ -84,3 +88,62 @@ pub fn hook(_: TokenStream, input: TokenStream) -> TokenStream {
output.into()
}
fn lit_to_bytes(lit: &Lit) -> Option<Vec<u8>> {
match lit {
Lit::Str(lit_str) => {
Some(lit_str.value().into_bytes())
}
Lit::ByteStr(lit_str) => {
Some(lit_str.value())
}
_ => {
None
}
}
}
#[proc_macro]
pub fn crc32(input: TokenStream) -> TokenStream {
let expr = parse_macro_input!(input as Lit);
match lit_to_bytes(&expr) {
Some(bytes) => {
let crc = crc::crc32::checksum_ieee(&bytes);
TokenStream::from(quote! {
(#crc)
})
}
None => {
let span = expr.span();
TokenStream::from(quote::quote_spanned!{span =>
compile_error!("Invalid literal");
})
}
}
}
#[proc_macro]
pub fn to_null_term_bytes(input: TokenStream) -> TokenStream {
let expr = parse_macro_input!(input as Lit);
match lit_to_bytes(&expr) {
Some(mut bytes) => {
bytes.push(0);
let bytes = syn::LitByteStr::new(&bytes, expr.span());
TokenStream::from(quote! {
(#bytes)
})
}
None => {
let span = expr.span();
TokenStream::from(quote::quote_spanned!{span =>
compile_error!("Invalid literal");
})
}
}
}

View file

@ -1,5 +1,3 @@
use core::any::Any;
#[lang = "eh_personality"]
extern fn eh_personality() {
}
@ -14,12 +12,20 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
global_asm!(include_str!("mod0.s"));
#[no_mangle] pub unsafe extern "C" fn __custom_init() {
}
#[no_mangle] pub unsafe extern "C" fn __custom_init() {}
#[no_mangle] pub extern "C" fn __custom_fini() {}
#[macro_export] macro_rules! set_module_name {
($lit:literal) => {
const __SKYLINE_INTERNAL_MODULE_LEN: usize = $lit.len() + 1;
#[link_section = ".rodata.module_name"]
pub static __MODULE_NAME: ::skyline::build::ModuleName<__SKYLINE_INTERNAL_MODULE_LEN> =
::skyline::build::ModuleName::new(
::skyline::skyline_macro::to_null_term_bytes!($lit)
);
};
}
#[repr(packed)]
#[allow(unused_variables)]
pub struct ModuleName<const LEN: usize> {
@ -32,15 +38,12 @@ impl<const LEN: usize> ModuleName<LEN> {
pub const fn new(bytes: &[u8; LEN]) -> Self {
Self {
unk: 0,
name_length: LEN as u32,
name_length: LEN as u32 - 1,
name: *bytes,
}
}
}
#[link_section = ".rodata.module_name"]
pub static MODULE_NAME: impl Any = ModuleName::new(b"no_std_test\0");
/// one-time setup for skyline
#[doc(hidden)]
#[macro_export] macro_rules! setup {

View file

@ -1,13 +1,17 @@
#![no_std]
#![allow(incomplete_features)]
#![feature(alloc_error_handler, lang_items, start, global_asm, const_generics, impl_trait_in_bindings, proc_macro_hygiene, alloc_prelude)]
#![feature(alloc_error_handler, lang_items, start, global_asm, const_generics, impl_trait_in_bindings, proc_macro_hygiene, alloc_prelude, const_if_match, const_loop)]
/// The rust core allocation and collections library
pub extern crate alloc;
#[doc(hidden)]
pub use skyline_macro;
/// Types and functions for working with hooking
pub mod hooks;
pub mod logging;
pub mod smash;
#[doc(hidden)]
pub mod extern_alloc;

View file

@ -0,0 +1,65 @@
/// const crc32 implementation by leo60288
macro_rules! reflect {
($bits:expr, $value:expr) => {{
let mut reflection = 0;
let mut value = $value;
let mut i = 0;
while i < $bits {
if (value & 0x01) == 1 {
reflection |= 1 << (($bits - 1) - i)
}
value >>= 1;
i += 1;
}
reflection
}};
}
const fn make_table(poly: u32) -> [u32; 256] {
let mut table = [0; 256];
let top_bit = 1 << 31;
let mut byte;
let mut i = 0;
while i <= 255 {
byte = reflect!(8, i);
let mut value = byte << 24;
let mut j = 0;
while j < 8 {
if (value & top_bit) != 0 {
value = (value << 1) ^ poly
} else {
value <<= 1
}
j += 1;
}
value = reflect!(32, value);
table[i as usize] = value;
i += 1;
}
table
}
const IEEE_TABLE: [u32; 256] = make_table(0x04C11DB7);
pub const fn crc32(bytes: &[u8]) -> u32 {
let mut value = !0u32;
let mut i = 0;
while i < bytes.len() {
value = (value >> 8) ^ (IEEE_TABLE[((value ^ (bytes[i] as u32)) & 0xFF) as usize]);
i += 1;
}
!value
}

8
skyline/src/smash/mod.rs Normal file
View file

@ -0,0 +1,8 @@
pub mod crc32;
// Find the hash40 of a given string
pub const fn hash40(string: &str) -> u64 {
let bytes = string.as_bytes();
((bytes.len() as u64) << 32) + crc32::crc32(bytes) as u64
}

View file

@ -2,8 +2,9 @@
#![feature(proc_macro_hygiene)]
use skyline::nn::account::{self, Uid, GetLastOpenedUser, GetNickname, Nickname};
use skyline::smash::hash40;
#[skyline::main]
#[skyline::main(name = "module_name_test")]
pub fn main() {
println!("Hello from Skyline Rust Plugin!\n");
@ -11,18 +12,18 @@ pub fn main() {
println!("{}", i);
}
init_accounts();
let nickname = unsafe { get_last_user_nickname() };
println!("Last nickname: {}", nickname);
}
fn init_accounts() {
unsafe { account::Initialize() };
println!("Compile-time hash40 of 'accel_x': {:010X}", hash40("accel_x"));
let string = "accel_x";
println!("Runtime hash40 of '{}': {:010X}", string, hash40(string));
}
unsafe fn get_last_user_nickname() -> Nickname {
account::Initialize();
let uid = &mut Uid::new();
let mut nick = Nickname::new();