Ir para conteúdo
  • Cadastre-se

Vote System 2020


Posts recomendados

Trago a vocês, um novo vote system que acabei desenvolvendo neste sábado (04/04/2020).

Estarei disponibilizando tanto a versão compilada quanto a source no final do tópico.

Vamos lá.

Informações das Tecnologias utilizadas.

O Sistema foi desenvolvido em .NET CORE 3.1, fugindo um pouco do padrão dos desenvolvedores do fórum que fazem quase tudo em PHP, logo você terá que ter uma hospedagem que aceite o NET CORE 3.1, ou você pode instalar o IIS em um servidor Windows ou o runtime no Linux para rodar.

Fiz utilizando Bootstrap, então é responsivo tanto para PC quanto para Mobile.

Banco de Dados.

Execute as seguintes SQL's em seu banco de dados.

create table votesystem_votos(
	id int NOT NULL AUTO_INCREMENT,
	login varchar(250) NOT NULL,
	ip varchar(50) NOT NULL,
	data_voto DATETIME NOT NULL,
	PRIMARY KEY (id)
);

create table votesystem_tops(
	id int NOT NULL AUTO_INCREMENT,
	link_votacao varchar(250) NOT NULL,
	nome_top varchar(150) NOT NULL,
	link_imagem varchar(250) NOT NULL,
	PRIMARY KEY (id)
);

create table votesystem_rewards(
	id int NOT NULL AUTO_INCREMENT,
	item_id int NOT NULL,
	quantidade int NOT NULL,
	enchant_level int NOT NULL DEFAULT 0,
	PRIMARY KEY (id)
);

 

Sobre as tabelas: 

Após executar as SQL's, vamos ver as tabelas.

Tabela: votesystem_rewards -> Você vai configurar quais items o usuário vai receber por votar no servidor, a quantidade de items é ilimitada, você pode informar quantos desejar.

Ex: quero que o usuario que votar recebe uma Gold Bar.

Logo no campo item_id vai receber o valor de 3470, o campo quantidade vai receber 1, enchant_level vai receber 0.

spacer.png

Tabela: votesystem_tops -> Você vai informar os top's para votação.

Em: link_votacao você vai informar a sua url do top para votar.

em nome_top você vai informar o nome.

em link_imagem você vai informar o banner do top que você quer que apareça no painel.

spacer.png

Algumas imagens do Vote System:

Spoiler

 

spacer.pngspacer.png

spacer.png

spacer.png

spacer.png

spacer.png

spacer.png

spacer.png

spacer.png

Como Configurar:

Após executar as SQL's e colocar o Vote System para rodar, você vai precisar configurar o arquivo app.config

Acesse o arquivo "app.config" e clique para editar ele.

Nele terão as seguintes informações:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!--- Tops que possuem API's de Validacao -->
    <!-- Atenção: Somente informe se deseja utilizar estes TOP's para validar os Votos. 
       Em caso de não informar, o Vote System não vai validar em nenhum, mas vai validar se o usuario já recebeu o reward no dia. -->
    <add key="l2jbrasil" value="l2draco"/> <!-- nome do servidor na l2jbrasil ex: l2draco, url onde se encontra: https://top.l2jbrasil.com/index.php?a=in&u=l2draco -->
    <add key="topmmo" value=""/> <!-- Sua chave do topmmo ex: k09e924db49b12d1 url onde se encontra: https://mmotop.eu/l2/data/k09e924db49b12d1 -->

    <!--- Nome do Servidor -->
    <add key="nomeServidor" value="Lineage 2"/>
    
    <!--- Configuração Banco de Dados -->
    <add key="host" value="127.0.0.1"/> <!-- IP do servidor (MySql/MariaDB) -->
    <add key="porta" value="3306"/> <!-- Porta (MySql/MariaDB) -->
    <add key="database" value="l2jserver"/> <!-- Nome banco de dados -->
    <add key="user" value="root"/> <!-- Usuario banco de dados -->
    <add key="senha" value="123456"/> <!-- Senha do banco de dados -->
  </appSettings>
</configuration>

Como funciona a validação ? 

A validação funciona com 2 Top's que tem API's, o sistema consulta e verifica se votou ou não.

Caso você não informar nada ali nas key's l2jbrasil e topmmo, o sistema ele não vai validar por nenhuma API se o usuário votou ou não.

Sendo assim, ele apenas vai verificar no banco se o usuário já votou no dia com determinado login/ip.

Spoiler

spacer.png

Link Download Projeto Compiladohttps://github.com/DZ1M/VoteSystemL2j/raw/master/VoteSystem.rar

Link do Projeto no GITHUBhttps://github.com/DZ1M/VoteSystemL2j

 

Editado por DZ1M

"Seja feliz do jeito que você é, não mude sua rotina pelo o que os outros exigem de você, simplesmente viva de acordo com o seu modo de viver."

(Yato - Noragami)

 

 

Link para o comentário
Compartilhar em outros sites


Parabens man otimo trabalho, to instalando ele pra testar.

 

Vc que manja deixa eu te perguntar teria como colocar mais de um item pra voto mais da seguinte forma, 

Exemplo: 1° voto item x , 2° voto item xx , 3° voto item xxx

Se sim como eu faria isso 

 

asinaturaskull.jpg
Link para o comentário
Compartilhar em outros sites

5 horas atrás, sergiommjr disse:

Parabens man otimo trabalho, to instalando ele pra testar.

 

Vc que manja deixa eu te perguntar teria como colocar mais de um item pra voto mais da seguinte forma, 

Exemplo: 1° voto item x , 2° voto item xx , 3° voto item xxx

Se sim como eu faria isso 

 

Não fiz desta forma, mas é bem tranquilo fazer uma verificação e adicionar isto.

Tipo, cria mais uma coluna na tabela votesystem_rewards para informar o reward a partir de tantos votos em cada item.

Na pasta Services, em ConsultaService.cs , vá no método BuscaRewards e ali você pode fazer uma verificação destas como você quer.

Tipo, verifica se o player tem tantos votos na tabela votesystem_votos pelo login/ip, se tiver dai ele busca tal reward.

Qualquer coisa, mais tarde eu faço e aplico um commit na source do projeto com esta sua solicitação;.

 

 

"Seja feliz do jeito que você é, não mude sua rotina pelo o que os outros exigem de você, simplesmente viva de acordo com o seu modo de viver."

(Yato - Noragami)

 

 

Link para o comentário
Compartilhar em outros sites

2 horas atrás, DZ1M disse:

Não fiz desta forma, mas é bem tranquilo fazer uma verificação e adicionar isto.

Tipo, cria mais uma coluna na tabela votesystem_rewards para informar o reward a partir de tantos votos em cada item.

Na pasta Services, em ConsultaService.cs , vá no método BuscaRewards e ali você pode fazer uma verificação destas como você quer.

Tipo, verifica se o player tem tantos votos na tabela votesystem_votos pelo login/ip, se tiver dai ele busca tal reward.

Qualquer coisa, mais tarde eu faço e aplico um commit na source do projeto com esta sua solicitação;.

 

 

Pou cara kkkk vendo vc falar assim é facinho kkkkk mais nem vou fazer isso kkkk manjo nada de estrutura de script php nada disso, coloquei pra rodar aque e testar aparentemente funcionando perfeitamente.... E se vc conseguir mesmo fazer esse metodo vai ficar show....

Por momento parabéns

asinaturaskull.jpg
Link para o comentário
Compartilhar em outros sites

1 hora atrás, sergiommjr disse:

Pou cara kkkk vendo vc falar assim é facinho kkkkk mais nem vou fazer isso kkkk manjo nada de estrutura de script php nada disso, coloquei pra rodar aque e testar aparentemente funcionando perfeitamente.... E se vc conseguir mesmo fazer esse metodo vai ficar show....

Por momento parabéns

Já fiz, commit: https://github.com/DZ1M/VoteSystemL2j/commit/82b37d2dedc973ddd29aee58b78260108c3b79e2

Download do projeto já compilado e as tabelas para executar novamente.

https://www.mediafire.com/file/io1zx6i7ftgojo0/VoteSystem.rar/file

Não cheguei a testar ainda, mas deve estar funcionando.

Já mando uma print de como configurar.

--- Edit ---spacer.png

de 0 até 1 significa que se o jogador não votou ou tiver 1 voto ele vai ganhar este reward.

Se ele tiver 2 até 5 vai ganhar o outro reward.

de 5 até 100 vai ganhar outro...

Pode configurar do teu modo.

Logo mais vou testar estas mudanças que fiz e qualquer novo ajuste atualizo.

 

Obs: Se forem utilizar o vote system acima, baixem ele novamente, foi ajustado um bug na lógica de entrega dos itens.

https://www.mediafire.com/file/io1zx6i7ftgojo0/VoteSystem.rar/file

Testado e funcional.

 

Editado por DZ1M
Corrigindo bug de lógica na ultima versão.

"Seja feliz do jeito que você é, não mude sua rotina pelo o que os outros exigem de você, simplesmente viva de acordo com o seu modo de viver."

(Yato - Noragami)

 

 

Link para o comentário
Compartilhar em outros sites

  • 2 weeks later...
  • 2 weeks later...
Em 20/04/2020 at 05:06, sergiommjr disse:

Amigo só uma pergunta kkk como eu faria para fazer ele rodar em localhost, apenas para eu editar ele, teria como, mesmo que eu nao consiga votar apenas para eu editar mesmo...

E que na hospedagem ele funcionou mais aque em casa não kkkk

Utilizando o Visual Studio e instalado o Net Core, ou instalando o IIS e adicionando ele para rodar.

 

"Seja feliz do jeito que você é, não mude sua rotina pelo o que os outros exigem de você, simplesmente viva de acordo com o seu modo de viver."

(Yato - Noragami)

 

 

Link para o comentário
Compartilhar em outros sites

  • 3 months later...
  • 3 years later...
  • Registre-se

    Faça parte da maior e  mais antigas comunidades sobre Lineage2 da América Latina.





  • Patrocinadores

  • Quem Está Navegando

    • Nenhum usuário registrado visualizando esta página.
  • Posts

    • Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?    
    • muchas gracias muy lindos NPC 🙂
    • relaxa jovem gafanhoto, testa as quests. e posTa os erros indesejaveis.  
    • Se alguém pudesse me ensinar como codificar as missões, eu ficaria feliz em fazer isso sozinho ou pelo menos ajudar. Eu realmente quero jogar em um servidor onde todas as quests funcionem bem e melhor ainda se você puder fazer quests customizadas!
    • mas no interlude, nem todas as quests de class,  vai mostrar onde tem que ir, ate o reborn nao mostrava quando era interlude, só mostrou depois que eles colocaram client classic pra rodar, e ficou melhor ainda quando virou hellbound em diante, mas ha sim alguma chance de modificar isso direto no script para fazer igualmente, só basta te um pouco de paciencia e persistencia exato
    • 408_PathToElvenwizard dá Orion eu tive que mexer tbm, até modifiquei e consegui deixar ela igual do Classic, com a seta e a marcação no mapa. (não retail IL) Dá pra importar py de várias revs, o foda é que não da regular as quest py através do debug em tempo real, pelo menos eu não consegui rsrs
    • Hasta el momento todas las QUESTS son completables si te guias con un tutorial de youtube. El problema es que tienen bugs de locacion y de subquests que no avanzan o no te marcan correctamente a donde ir en el mapa, cosa que en Retail si se ve como corresponde.
    • estranho, mas pelo menos a galera nunca reclamo das quests quando tinha aberto 5x, geral fez class primeira e segunda job, poucos que compraram a class
    • en RUSaCis-3.5 data pack, las Quests estan en formato .java y son diferentes a como estan redactadas en jOrion y jFrozen 1.5 (ProyectX) package net.sf.l2j.gameserver.scripting.quest; import net.sf.l2j.commons.random.Rnd; import net.sf.l2j.gameserver.enums.Paperdoll; import net.sf.l2j.gameserver.enums.QuestStatus; import net.sf.l2j.gameserver.enums.actors.ClassId; import net.sf.l2j.gameserver.model.actor.Creature; import net.sf.l2j.gameserver.model.actor.Npc; import net.sf.l2j.gameserver.model.actor.Player; import net.sf.l2j.gameserver.network.serverpackets.SocialAction; import net.sf.l2j.gameserver.scripting.QuestState; public class Q224_TestOfSagittarius extends SecondClassQuest { private static final String QUEST_NAME = "Q224_TestOfSagittarius"; // Items private static final int BERNARD_INTRODUCTION = 3294; private static final int HAMIL_LETTER_1 = 3295; private static final int HAMIL_LETTER_2 = 3296; private static final int HAMIL_LETTER_3 = 3297; private static final int HUNTER_RUNE_1 = 3298; private static final int HUNTER_RUNE_2 = 3299; private static final int TALISMAN_OF_KADESH = 3300; private static final int TALISMAN_OF_SNAKE = 3301; private static final int MITHRIL_CLIP = 3302; private static final int STAKATO_CHITIN = 3303; private static final int REINFORCED_BOWSTRING = 3304; private static final int MANASHEN_HORN = 3305; private static final int BLOOD_OF_LIZARDMAN = 3306; private static final int CRESCENT_MOON_BOW = 3028; private static final int WOODEN_ARROW = 17; // Rewards private static final int MARK_OF_SAGITTARIUS = 3293; // NPCs private static final int BERNARD = 30702; private static final int HAMIL = 30626; private static final int SIR_ARON_TANFORD = 30653; private static final int VOKIAN = 30514; private static final int GAUEN = 30717; // Monsters private static final int ANT = 20079; private static final int ANT_CAPTAIN = 20080; private static final int ANT_OVERSEER = 20081; private static final int ANT_RECRUIT = 20082; private static final int ANT_PATROL = 20084; private static final int ANT_GUARD = 20086; private static final int NOBLE_ANT = 20089; private static final int NOBLE_ANT_LEADER = 20090; private static final int BREKA_ORC_SHAMAN = 20269; private static final int BREKA_ORC_OVERLORD = 20270; private static final int MARSH_STAKATO_WORKER = 20230; private static final int MARSH_STAKATO_SOLDIER = 20232; private static final int MARSH_STAKATO_DRONE = 20234; private static final int MARSH_SPIDER = 20233; private static final int ROAD_SCAVENGER = 20551; private static final int MANASHEN_GARGOYLE = 20563; private static final int LETO_LIZARDMAN = 20577; private static final int LETO_LIZARDMAN_ARCHER = 20578; private static final int LETO_LIZARDMAN_SOLDIER = 20579; private static final int LETO_LIZARDMAN_WARRIOR = 20580; private static final int LETO_LIZARDMAN_SHAMAN = 20581; private static final int LETO_LIZARDMAN_OVERLORD = 20582; private static final int SERPENT_DEMON_KADESH = 27090; public Q224_TestOfSagittarius() { super(224, "Test Of Sagittarius"); setItemsIds(BERNARD_INTRODUCTION, HAMIL_LETTER_1, HAMIL_LETTER_2, HAMIL_LETTER_3, HUNTER_RUNE_1, HUNTER_RUNE_2, TALISMAN_OF_KADESH, TALISMAN_OF_SNAKE, MITHRIL_CLIP, STAKATO_CHITIN, REINFORCED_BOWSTRING, MANASHEN_HORN, BLOOD_OF_LIZARDMAN, CRESCENT_MOON_BOW); addQuestStart(BERNARD); addTalkId(BERNARD, HAMIL, SIR_ARON_TANFORD, VOKIAN, GAUEN); addMyDying(ANT, ANT_CAPTAIN, ANT_OVERSEER, ANT_RECRUIT, ANT_PATROL, ANT_GUARD, NOBLE_ANT, NOBLE_ANT_LEADER, BREKA_ORC_SHAMAN, BREKA_ORC_OVERLORD, MARSH_STAKATO_WORKER, MARSH_STAKATO_SOLDIER, MARSH_STAKATO_DRONE, MARSH_SPIDER, ROAD_SCAVENGER, MANASHEN_GARGOYLE, LETO_LIZARDMAN, LETO_LIZARDMAN_ARCHER, LETO_LIZARDMAN_SOLDIER, LETO_LIZARDMAN_WARRIOR, LETO_LIZARDMAN_SHAMAN, LETO_LIZARDMAN_OVERLORD, SERPENT_DEMON_KADESH); } @Override public String onAdvEvent(String event, Npc npc, Player player) { String htmltext = event; QuestState st = player.getQuestList().getQuestState(QUEST_NAME); if (st == null) return htmltext; // BERNARD if (event.equalsIgnoreCase("30702-04.htm")) { st.setState(QuestStatus.STARTED); st.setCond(1); playSound(player, SOUND_ACCEPT); giveItems(player, BERNARD_INTRODUCTION, 1); if (giveDimensionalDiamonds39(player)) htmltext = "30702-04a.htm"; } // HAMIL else if (event.equalsIgnoreCase("30626-03.htm")) { st.setCond(2); playSound(player, SOUND_MIDDLE); takeItems(player, BERNARD_INTRODUCTION, 1); giveItems(player, HAMIL_LETTER_1, 1); } else if (event.equalsIgnoreCase("30626-07.htm")) { st.setCond(5); playSound(player, SOUND_MIDDLE); takeItems(player, HUNTER_RUNE_1, 10); giveItems(player, HAMIL_LETTER_2, 1); } // SIR_ARON_TANFORD else if (event.equalsIgnoreCase("30653-02.htm")) { st.setCond(3); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_1, 1); } // VOKIAN else if (event.equalsIgnoreCase("30514-02.htm")) { st.setCond(6); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_2, 1); } return htmltext; } @Override public String onTalk(Npc npc, Player player) { String htmltext = getNoQuestMsg(); QuestState st = player.getQuestList().getQuestState(QUEST_NAME); if (st == null) return htmltext; switch (st.getState()) { case CREATED: if (player.getClassId() != ClassId.ROGUE && player.getClassId() != ClassId.ELVEN_SCOUT && player.getClassId() != ClassId.ASSASSIN) htmltext = "30702-02.htm"; else if (player.getStatus().getLevel() < 39) htmltext = "30702-01.htm"; else htmltext = "30702-03.htm"; break; case STARTED: int cond = st.getCond(); switch (npc.getNpcId()) { case BERNARD: htmltext = "30702-05.htm"; break; case HAMIL: if (cond == 1) htmltext = "30626-01.htm"; else if (cond == 2 || cond == 3) htmltext = "30626-04.htm"; else if (cond == 4) htmltext = "30626-05.htm"; else if (cond > 4 && cond < 8) htmltext = "30626-08.htm"; else if (cond == 8) { htmltext = "30626-09.htm"; st.setCond(9); playSound(player, SOUND_MIDDLE); takeItems(player, HUNTER_RUNE_2, 10); giveItems(player, HAMIL_LETTER_3, 1); } else if (cond > 8 && cond < 12) htmltext = "30626-10.htm"; else if (cond == 12) { htmltext = "30626-11.htm"; st.setCond(13); playSound(player, SOUND_MIDDLE); } else if (cond == 13) htmltext = "30626-12.htm"; else if (cond == 14) { htmltext = "30626-13.htm"; takeItems(player, BLOOD_OF_LIZARDMAN, -1); takeItems(player, CRESCENT_MOON_BOW, 1); takeItems(player, TALISMAN_OF_KADESH, 1); giveItems(player, MARK_OF_SAGITTARIUS, 1); rewardExpAndSp(player, 54726, 20250); player.broadcastPacket(new SocialAction(player, 3)); playSound(player, SOUND_FINISH); st.exitQuest(false); } break; case SIR_ARON_TANFORD: if (cond == 2) htmltext = "30653-01.htm"; else if (cond > 2) htmltext = "30653-03.htm"; break; case VOKIAN: if (cond == 5) htmltext = "30514-01.htm"; else if (cond == 6) htmltext = "30514-03.htm"; else if (cond == 7) { htmltext = "30514-04.htm"; st.setCond(8); playSound(player, SOUND_MIDDLE); takeItems(player, TALISMAN_OF_SNAKE, 1); } else if (cond > 7) htmltext = "30514-05.htm"; break; case GAUEN: if (cond == 9) { htmltext = "30717-01.htm"; st.setCond(10); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_3, 1); } else if (cond == 10) htmltext = "30717-03.htm"; else if (cond == 11) { htmltext = "30717-02.htm"; st.setCond(12); playSound(player, SOUND_MIDDLE); takeItems(player, MANASHEN_HORN, 1); takeItems(player, MITHRIL_CLIP, 1); takeItems(player, REINFORCED_BOWSTRING, 1); takeItems(player, STAKATO_CHITIN, 1); giveItems(player, CRESCENT_MOON_BOW, 1); giveItems(player, WOODEN_ARROW, 10); } else if (cond > 11) htmltext = "30717-04.htm"; break; } break; case COMPLETED: htmltext = getAlreadyCompletedMsg(); break; } return htmltext; } @Override public void onMyDying(Npc npc, Creature killer) { final Player player = killer.getActingPlayer(); final QuestState st = checkPlayerState(player, npc, QuestStatus.STARTED); if (st == null) return; switch (npc.getNpcId()) { case ANT: case ANT_CAPTAIN: case ANT_OVERSEER: case ANT_RECRUIT: case ANT_PATROL: case ANT_GUARD: case NOBLE_ANT: case NOBLE_ANT_LEADER: if (st.getCond() == 3 && dropItems(player, HUNTER_RUNE_1, 1, 10, 500000)) st.setCond(4); break; case BREKA_ORC_SHAMAN: case BREKA_ORC_OVERLORD: if (st.getCond() == 6 && dropItems(player, HUNTER_RUNE_2, 1, 10, 500000)) { st.setCond(7); giveItems(player, TALISMAN_OF_SNAKE, 1); } break; case MARSH_STAKATO_WORKER: case MARSH_STAKATO_SOLDIER: case MARSH_STAKATO_DRONE: if (st.getCond() == 10 && dropItems(player, STAKATO_CHITIN, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, MITHRIL_CLIP, REINFORCED_BOWSTRING)) st.setCond(11); break; case MARSH_SPIDER: if (st.getCond() == 10 && dropItems(player, REINFORCED_BOWSTRING, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, MITHRIL_CLIP, STAKATO_CHITIN)) st.setCond(11); break; case ROAD_SCAVENGER: if (st.getCond() == 10 && dropItems(player, MITHRIL_CLIP, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, REINFORCED_BOWSTRING, STAKATO_CHITIN)) st.setCond(11); break; case MANASHEN_GARGOYLE: if (st.getCond() == 10 && dropItems(player, MANASHEN_HORN, 1, 1, 100000) && player.getInventory().hasItems(REINFORCED_BOWSTRING, MITHRIL_CLIP, STAKATO_CHITIN)) st.setCond(11); break; case LETO_LIZARDMAN: case LETO_LIZARDMAN_ARCHER: case LETO_LIZARDMAN_SOLDIER: case LETO_LIZARDMAN_WARRIOR: case LETO_LIZARDMAN_SHAMAN: case LETO_LIZARDMAN_OVERLORD: if (st.getCond() == 13) { if (((player.getInventory().getItemCount(BLOOD_OF_LIZARDMAN) - 120) * 5) > Rnd.get(100)) { playSound(player, SOUND_BEFORE_BATTLE); takeItems(player, BLOOD_OF_LIZARDMAN, -1); addSpawn(SERPENT_DEMON_KADESH, player, false, 300000, true); } else dropItemsAlways(player, BLOOD_OF_LIZARDMAN, 1, 0); } break; case SERPENT_DEMON_KADESH: if (st.getCond() == 13) { if (player.getInventory().getItemIdFrom(Paperdoll.RHAND) == CRESCENT_MOON_BOW) { st.setCond(14); playSound(player, SOUND_MIDDLE); giveItems(player, TALISMAN_OF_KADESH, 1); } else addSpawn(SERPENT_DEMON_KADESH, player, false, 300000, true); } break; } } }  
×
×
  • Criar Novo...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.