-
Notifications
You must be signed in to change notification settings - Fork 0
SaveManager (pt)
O SaveManager é um ScriptableObject responsável por fornecer os métodos públicos Save() e Load(), salvando e carregando dados para o SaveContainer.
Antes de começar a utilizar o sistema, é necessário fazer uma configuração e deixar de acordo com suas preferências.
- Save File Name: Define o nome que será utilizado nos arquivos de save. Por padrão é "save".
- Save File Extension: Define a extensão que será utilizada no final dos arquivos de save. Por padrão a extensão é ".sav"
- Hash File Name: Define o nome que será utilizado nos arquivos de hash. Por padrão é "hash".
- Hash File Extension: Define a extensão que será utilizada no final do arquivo. Por padrão a extensão é ".hash"
- Current Slot: Slot de save atual. Por padrão o primeiro slot é selecionado.
- Save Path: Lugar onde o save será salvo, tendo as opções Persistent Data Path e Data Path. Por padrão o Persistent Data Path é selecionado.
- Protect Save: Ativa ou desativa a proteção dos saves. Por padrão é true.
- Shuffle Seed: Semente a ser usada no embaralhamento dos bytes, sendo qualquer número inteiro de 32 bits. Por padrão é 1.
- Hash Salt: "Sal" a ser adicionado ao hash do save, podendo ser qualquer texto. Por padrão é "salt423".
- Save Container: Referência de um Save Container.
O SaveManager contém alguns eventos do tipo Action, tendo possibilidade de atribuir métodos que serão chamados quando determinado acontecer.
- OnStartSave: Chamado quando começar a salvar.
- OnEndSave: Chamado quando terminar de salvar, tendo sucesso ou não.
- OnSaveSuccess: Chamado quando for salvo com sucesso.
- OnSaveError<Exception>: Chamado quando der algum erro durante a tentativa de salvar, passando um Exception como parâmetro.
- OnStartLoad: Chamado quando começar a carregar o save.
- OnEndLoad: Chamado quando terminar de carregar o save, tendo como sucesso ou não.
- OnLoadSuccess: Chamado quando for carregado com sucesso.
- OnLoadError<Exception>: Chamado quando der algum erro durante a tentativa de carregar o save, passando um Exception como parâmetro.
Quando o método Save() for chamado de algum outro script, ele começará dando invoke no Action OnStartSave, depois verificando se nome ou extensão do arquivo de save fornecido por você não estão vazios, se estiverem, retorna um Exception.
Depois da verificação, os dados contidos na classe SaveData dentro do SaveContainer serão convertidos em JSON, utilizando o método ToJson() da classe JsonUtility da própria Unity. Em seguida, criando uma instância de um FileStream, usando o caminho escolhido por você e usando o FileMode.Create.
Ele criará uma nova instância de um StreamWriter passando o FileStream criado anteriormente como parâmetro, depois escrevendo o JSON no arquivo.
Ele criará uma nova instância de um StreamWriter passando o caminho do arquivo Hash como parâmetro, depois escrevendo a hash dos dados junto com o "sal" gerada pelo método GetStringHash() da classe SaveIntegrityUtility.
Depois da hash ser gerada e salva, a função ShuffleBytes() da classe SaveIntegrityUtility é chamada dando como parâmetro os dados convertidos de UTF-8 para uma lista de bytes, e outro parâmetro sendo a seed definida por você.
Após o embaralhamento, um laço for é criado fazendo separar os bytes por espaços, em seguida é criado uma nova instância do BinaryWriter dando o FileStream como parâmetro, depois escrevendo os bytes separados em binário. No fim, o evento OnSaveSuccess é chamado.
Se caso houver algum erro, no bloco catch será chamado o evento OnSaveError passando o Exeception como parâmetro.
Quando o método Load() for chamado de algum outro script, ele começará dando invoke no Action OnStartLoad.
Ele irá instanciar um novo StreamReader passando como parâmetro o caminho do save, em seguida, ele lê o arquivo e armazena em uma string.
Ele irá criar uma nova instância de um FileStream, passando como parâmetro o caminho do save, e o segundo parâmetro sendo um FileMode.Open.
Depois uma nova instância do BinaryReader é criada, passando como parâmetro o FileStream instanciado anteriormente, e lendo o save que foi salvo em binário anteriormente.
Após a leitura, os bytes que estão separados passam por um laço foreach onde é usado o método Split() para pegar os bytes que foram divididos por espaços, em seguida ir incrementando numa lista de bytes.
Depois dos bytes serem passados pra uma lista de bytes, eles são desembaralhados com a seed que você definiu.
Os dados foram carregados, e em seguida, ele gera uma hash desses dados carregados e carrega a hash anterior usando um StreamReader.
As duas hashes são comparadas e se as duas estiverem iguais o algoritmo carrega com sucesso, se não estiverem iguais ou não haver a hash, o algoritmo retorna um Exception e não permite o carregamento do save.
Após todo esse processo, é usado o método FromJson() do JsonUtility para converter os dados em JSON para a classe SaveData, em seguida atribuindo os valores no SaveContainer e chamando o Action OnLoadSuccess.
Caso ocorra algum erro, o evento OnLoadError é chamado passando o Exception como parâmetro.