public static Amiibo BuildAmiibo(AmiiboAPI.Amiibo api_amiibo, string name) { ExceptionUtils.Unless(api_amiibo != null, "Invalid input amiibo"); var amiibo = new Amiibo { OriginalAmiibo = api_amiibo, }; try { amiibo.Name = name; amiibo.MiiCharInfoFileName = "mii-charinfo.bin"; var cur_date = DateTime.Now; amiibo.FirstWriteDate.Year = (ushort)cur_date.Year; amiibo.FirstWriteDate.Month = (byte)cur_date.Month; amiibo.FirstWriteDate.Day = (byte)cur_date.Day; amiibo.LastWriteDate = amiibo.FirstWriteDate; var id = api_amiibo.AmiiboId; ExceptionUtils.Unless(id.Length == 16, "Invalid amiibo ID"); var character_game_id_str = id.Substring(0, 4); var character_variant_str = id.Substring(4, 2); var figure_type_str = id.Substring(6, 2); var model_no_str = id.Substring(8, 4); var series_str = id.Substring(12, 2); // Swap endianness for this number var character_game_id_be = ushort.Parse(character_game_id_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.CharacterId.GameCharacterId = NumberUtils.Reverse(character_game_id_be); amiibo.Id.CharacterId.CharacterVariant = byte.Parse(character_variant_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.FigureType = byte.Parse(figure_type_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.ModelNumber = ushort.Parse(model_no_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.Series = byte.Parse(series_str, System.Globalization.NumberStyles.HexNumber); // Generate a random UUID // In most UUIDs, the first 7 bytes are random, while the last three are zeroed // Since some games, like Splatoon 2, seem to check if these are zeroed, we'll follow this pattern and zero last 3 bytes Random rnd = new Random(); rnd.NextBytes(amiibo.Uuid); amiibo.Uuid[7] = 0; amiibo.Uuid[8] = 0; amiibo.Uuid[9] = 0; } catch (Exception ex) { ExceptionUtils.LogExceptionMessage(ex); } return(amiibo); }
public static Amiibo BuildAmiibo(AmiiboAPI.Amiibo api_amiibo, string name) { ExceptionUtils.Unless(api_amiibo != null, "Invalid input amiibo"); var amiibo = new Amiibo(); amiibo.OriginalAmiibo = api_amiibo; try { amiibo.Name = name; amiibo.MiiCharInfoFileName = "mii-charinfo.bin"; var cur_date = DateTime.Now; amiibo.FirstWriteDate.Year = (ushort)cur_date.Year; amiibo.FirstWriteDate.Month = (byte)cur_date.Month; amiibo.FirstWriteDate.Day = (byte)cur_date.Day; amiibo.LastWriteDate = amiibo.FirstWriteDate; var id = api_amiibo.AmiiboId; ExceptionUtils.Unless(id.Length == 16, "Invalid amiibo ID"); var character_game_id_str = id.Substring(0, 4); var character_variant_str = id.Substring(4, 2); var figure_type_str = id.Substring(6, 2); var model_no_str = id.Substring(8, 4); var series_str = id.Substring(12, 2); // Swap endianness for this number var character_game_id_be = ushort.Parse(character_game_id_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.CharacterId.GameCharacterId = NumberUtils.Reverse(character_game_id_be); amiibo.Id.CharacterId.CharacterVariant = byte.Parse(character_variant_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.FigureType = byte.Parse(figure_type_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.ModelNumber = ushort.Parse(model_no_str, System.Globalization.NumberStyles.HexNumber); amiibo.Id.Series = byte.Parse(series_str, System.Globalization.NumberStyles.HexNumber); // Generate a random UUID Random rnd = new Random(); rnd.NextBytes(amiibo.Uuid); } catch (Exception ex) { ExceptionUtils.LogExceptionMessage(ex); } return(amiibo); }
private void CreateAmiibo(string name, string dir_name, string base_dir, AmiiboAPI.Amiibo cur_amiibo) { string out_path; bool use_last_path = LastPathCheck.Checked; if (use_last_path) { if (string.IsNullOrEmpty(LastUsedPath)) { use_last_path = false; } } bool save_to_ftp = FtpSaveCheck.Checked; IPAddress ftp_ip = null; int ftp_port = 0; // For FTP, use a temp directory to save the resulting files from amiibo.Save() before transfer var ftp_tmp_path = Path.Combine(Environment.CurrentDirectory, "temp_ftp"); var ftp_sd_folder = "/emuiibo/amiibo/"; if (!string.IsNullOrEmpty(dir_name)) { ftp_sd_folder += $"{dir_name}/"; } if (save_to_ftp) { // Prepare FTP path out_path = Path.Combine(ftp_tmp_path, dir_name); // Validate the FTP address if (!IPAddress.TryParse(FtpAddressBox.Text, out ftp_ip)) { ShowErrorBox("FTP address is invalid"); return; } if (!int.TryParse(FtpPortBox.Text, out ftp_port)) { ShowErrorBox("FTP port is invalid"); return; } } else { if (use_last_path) { out_path = Path.Combine(LastUsedPath, dir_name); } else { out_path = Path.Combine(base_dir, dir_name); } } // Actually save the amiibo var amiibo = AmiiboUtils.BuildAmiibo(cur_amiibo, name); amiibo.Save(out_path, RandomizeUuidCheck.Checked, SaveImageCheck.Checked); // Special handling for FTP if (save_to_ftp) { var success = true; using (var client = new FtpClient(ftp_ip.ToString(), ftp_port, new NetworkCredential("", ""))) { client.ConnectTimeout = 1000; client.Connect(); foreach (var file in Directory.GetFiles(out_path)) { var file_name = Path.GetFileName(file); // Upload each file created, creating directories along the way var status = client.UploadFile(file, ftp_sd_folder + file_name, createRemoteDir: true); if (status != FtpStatus.Success) { success = false; break; } } client.Disconnect(); } ExceptionUtils.Unless(success, "Error during FTP upload, please try again"); // Clean the temp directory Directory.Delete(ftp_tmp_path, true); } else { if (!use_last_path) { // Update last used path LastUsedPath = base_dir; } } }
private void Button1_Click(object sender, EventArgs e) { try { var cur_amiibo = CurrentSeriesAmiibos[AmiiboComboBox.SelectedIndex]; if (string.IsNullOrEmpty(AmiiboNameBox.Text)) { ShowErrorBox("No amiibo name was specified."); return; } bool use_name_as_dir = UseNameCheck.Checked; if (!use_name_as_dir && string.IsNullOrEmpty(DirectoryNameBox.Text)) { ShowErrorBox("No amiibo directory name was specified."); return; } string name = AmiiboNameBox.Text; string dir_name = name; if (!use_name_as_dir) { dir_name = DirectoryNameBox.Text; } string out_path = ""; bool use_last_path = LastPathCheck.Checked; if (use_last_path) { if (string.IsNullOrEmpty(LastUsedPath)) { use_last_path = false; } } bool save_to_ftp = FtpSaveCheck.Checked; IPAddress ftp_ip = null; int ftp_port = 0; // For FTP, use a temp directory to save the resulting files from amiibo.Save() before transfer var ftp_tmp_path = Path.Combine(Environment.CurrentDirectory, "temp_ftp"); var ftp_sd_folder = $"/emuiibo/amiibo/{dir_name}/"; var selected_path = ""; if (save_to_ftp) { // Prepare FTP path out_path = Path.Combine(ftp_tmp_path, dir_name); // Validate the FTP address if (!IPAddress.TryParse(FtpAddressBox.Text, out ftp_ip)) { ShowErrorBox("FTP address is invalid"); return; } if (!int.TryParse(FtpPortBox.Text, out ftp_port)) { ShowErrorBox("FTP port is invalid"); return; } if (CancelAmiiboCreation($"'ftp://{ftp_ip.ToString()}:{ftp_port}{ftp_sd_folder}'")) { // User cancelled return; } } else { if (use_last_path) { if (CancelAmiiboCreation("the last used path")) { // User cancelled return; } out_path = Path.Combine(LastUsedPath, dir_name); } else { // If we're saving normally and we're not using the last path, ask the user for the path selected_path = SelectDirectory(); if (selected_path == null) { // User cancelled return; } out_path = Path.Combine(selected_path, dir_name); if (CancelAmiiboCreation($"'{out_path}'")) { // User cancelled return; } } } // Actually save the amiibo var amiibo = AmiiboUtils.BuildAmiibo(cur_amiibo, name); amiibo.Save(out_path, RandomizeUuidCheck.Checked, SaveImageCheck.Checked); // Special handling for FTP if (save_to_ftp) { var success = true; using (var client = new FtpClient(ftp_ip.ToString(), ftp_port, new NetworkCredential("", ""))) { client.ConnectTimeout = 1000; client.Connect(); foreach (var file in Directory.GetFiles(out_path)) { var file_name = Path.GetFileName(file); // Upload each file created, creating directories along the way var status = client.UploadFile(file, ftp_sd_folder + file_name, createRemoteDir: true); if (status != FtpStatus.Success) { success = false; break; } } client.Disconnect(); } ExceptionUtils.Unless(success, "Error during FTP upload, please try again"); // Clean the temp directory Directory.Delete(ftp_tmp_path, true); } else { if (!use_last_path) { // Update last used path LastUsedPath = selected_path; } } MessageBox.Show("The virtual amiibo was successfully created.", DialogCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { ExceptionUtils.LogExceptionMessage(ex); } LastPathLabel.Visible = LastPathCheck.Visible = !string.IsNullOrEmpty(LastUsedPath); if (LastPathLabel.Visible) { LastPathLabel.Text = "Last path: " + LastUsedPath; } }